diff options
| author | bors <bors@rust-lang.org> | 2022-01-18 09:58:39 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-01-18 09:58:39 +0000 |
| commit | 7bc7be860f99f4a40d45b0f74e2d01b02e072357 (patch) | |
| tree | bae7d965ae2524594d217ae3022513e7c929ea2c /src | |
| parent | 7531d2fdd49966d83830a7b4596c95587b1e9573 (diff) | |
| parent | b77bb5cb2589246cf684431ad2a184466940633d (diff) | |
| download | rust-7bc7be860f99f4a40d45b0f74e2d01b02e072357.tar.gz rust-7bc7be860f99f4a40d45b0f74e2d01b02e072357.zip | |
Auto merge of #87648 - JulianKnodt:const_eq_constrain, r=oli-obk
allow eq constraints on associated constants Updates #70256 (cc `@varkor,` `@Centril)`
Diffstat (limited to 'src')
28 files changed, 304 insertions, 102 deletions
diff --git a/src/etc/check_missing_items.py b/src/etc/check_missing_items.py index 7ed317c778f..de1717b3f3f 100644 --- a/src/etc/check_missing_items.py +++ b/src/etc/check_missing_items.py @@ -83,7 +83,9 @@ def check_type(ty): check_type(arg["const"]["type"]) for binding in args["angle_bracketed"]["bindings"]: if "equality" in binding["binding"]: - check_type(binding["binding"]["equality"]) + term = binding["binding"]["equality"] + if "type" in term: check_type(term["type"]) + elif "const" in term: check_type(term["const"]) elif "constraint" in binding["binding"]: for bound in binding["binding"]["constraint"]: check_generic_bound(bound) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 09692d27e8f..18a4d8a4753 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -553,8 +553,10 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { if self.is_fn_trait(trait_) && left_name == sym::Output { ty_to_fn .entry(*ty.clone()) - .and_modify(|e| *e = (e.0.clone(), Some(rhs.clone()))) - .or_insert((None, Some(rhs))); + .and_modify(|e| { + *e = (e.0.clone(), Some(rhs.ty().unwrap().clone())) + }) + .or_insert((None, Some(rhs.ty().unwrap().clone()))); continue; } @@ -570,7 +572,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { GenericArgs::AngleBracketed { ref mut bindings, .. } => { bindings.push(TypeBinding { name: left_name, - kind: TypeBindingKind::Equality { ty: rhs }, + kind: TypeBindingKind::Equality { term: rhs }, }); } GenericArgs::Parenthesized { .. } => { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index a5bc70a74ae..e759baa0458 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -272,9 +272,10 @@ impl Clean<WherePredicate> for hir::WherePredicate<'_> { bounds: wrp.bounds.iter().filter_map(|x| x.clean(cx)).collect(), }, - hir::WherePredicate::EqPredicate(ref wrp) => { - WherePredicate::EqPredicate { lhs: wrp.lhs_ty.clean(cx), rhs: wrp.rhs_ty.clean(cx) } - } + hir::WherePredicate::EqPredicate(ref wrp) => WherePredicate::EqPredicate { + lhs: wrp.lhs_ty.clean(cx), + rhs: wrp.rhs_ty.clean(cx).into(), + }, } } } @@ -352,10 +353,31 @@ impl<'tcx> Clean<Option<WherePredicate>> for ty::OutlivesPredicate<Ty<'tcx>, ty: } } +impl<'tcx> Clean<Term> for ty::Term<'tcx> { + fn clean(&self, cx: &mut DocContext<'_>) -> Term { + match self { + ty::Term::Ty(ty) => Term::Type(ty.clean(cx)), + ty::Term::Const(c) => Term::Constant(c.clean(cx)), + } + } +} + +impl<'tcx> Clean<Term> for hir::Term<'tcx> { + fn clean(&self, cx: &mut DocContext<'_>) -> Term { + match self { + hir::Term::Ty(ty) => Term::Type(ty.clean(cx)), + hir::Term::Const(c) => { + let def_id = cx.tcx.hir().local_def_id(c.hir_id); + Term::Constant(ty::Const::from_anon_const(cx.tcx, def_id).clean(cx)) + } + } + } +} + impl<'tcx> Clean<WherePredicate> for ty::ProjectionPredicate<'tcx> { fn clean(&self, cx: &mut DocContext<'_>) -> WherePredicate { - let ty::ProjectionPredicate { projection_ty, ty } = self; - WherePredicate::EqPredicate { lhs: projection_ty.clean(cx), rhs: ty.clean(cx) } + let ty::ProjectionPredicate { projection_ty, term } = self; + WherePredicate::EqPredicate { lhs: projection_ty.clean(cx), rhs: term.clean(cx) } } } @@ -613,7 +635,7 @@ fn clean_ty_generics( if let Some(param_idx) = param_idx { if let Some(b) = impl_trait.get_mut(¶m_idx.into()) { - let p = p.clean(cx)?; + let p: WherePredicate = p.clean(cx)?; b.extend( p.get_bounds() @@ -624,11 +646,16 @@ fn clean_ty_generics( ); let proj = projection - .map(|p| (p.skip_binder().projection_ty.clean(cx), p.skip_binder().ty)); + .map(|p| (p.skip_binder().projection_ty.clean(cx), p.skip_binder().term)); if let Some(((_, trait_did, name), rhs)) = proj.as_ref().and_then(|(lhs, rhs)| Some((lhs.projection()?, rhs))) { - impl_trait_proj.entry(param_idx).or_default().push((trait_did, name, rhs)); + // FIXME(...): Remove this unwrap() + impl_trait_proj.entry(param_idx).or_default().push(( + trait_did, + name, + rhs.ty().unwrap(), + )); } return None; @@ -647,7 +674,7 @@ fn clean_ty_generics( if let Some(proj) = impl_trait_proj.remove(&idx) { for (trait_did, name, rhs) in proj { let rhs = rhs.clean(cx); - simplify::merge_bounds(cx, &mut bounds, trait_did, name, &rhs); + simplify::merge_bounds(cx, &mut bounds, trait_did, name, &Term::Type(rhs)); } } } else { @@ -1495,7 +1522,9 @@ impl<'tcx> Clean<Type> for Ty<'tcx> { for pb in obj.projection_bounds() { bindings.push(TypeBinding { name: cx.tcx.associated_item(pb.item_def_id()).ident.name, - kind: TypeBindingKind::Equality { ty: pb.skip_binder().ty.clean(cx) }, + kind: TypeBindingKind::Equality { + term: pb.skip_binder().term.clean(cx).into(), + }, }); } @@ -1566,7 +1595,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> { .ident .name, kind: TypeBindingKind::Equality { - ty: proj.ty.clean(cx), + term: proj.term.clean(cx), }, }) } else { @@ -2114,10 +2143,10 @@ impl Clean<TypeBinding> for hir::TypeBinding<'_> { impl Clean<TypeBindingKind> for hir::TypeBindingKind<'_> { fn clean(&self, cx: &mut DocContext<'_>) -> TypeBindingKind { match *self { - hir::TypeBindingKind::Equality { ref ty } => { - TypeBindingKind::Equality { ty: ty.clean(cx) } + hir::TypeBindingKind::Equality { ref term } => { + TypeBindingKind::Equality { term: term.clean(cx) } } - hir::TypeBindingKind::Constraint { bounds } => TypeBindingKind::Constraint { + hir::TypeBindingKind::Constraint { ref bounds } => TypeBindingKind::Constraint { bounds: bounds.iter().filter_map(|b| b.clean(cx)).collect(), }, } diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index 4c81e75e8d6..0bad1532808 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -92,7 +92,7 @@ crate fn merge_bounds( bounds: &mut Vec<clean::GenericBound>, trait_did: DefId, name: Symbol, - rhs: &clean::Type, + rhs: &clean::Term, ) -> bool { !bounds.iter_mut().any(|b| { let trait_ref = match *b { @@ -110,14 +110,14 @@ crate fn merge_bounds( PP::AngleBracketed { ref mut bindings, .. } => { bindings.push(clean::TypeBinding { name, - kind: clean::TypeBindingKind::Equality { ty: rhs.clone() }, + kind: clean::TypeBindingKind::Equality { term: rhs.clone() }, }); } PP::Parenthesized { ref mut output, .. } => match output { - Some(o) => assert_eq!(o.as_ref(), rhs), + Some(o) => assert_eq!(&clean::Term::Type(o.as_ref().clone()), rhs), None => { - if *rhs != clean::Type::Tuple(Vec::new()) { - *output = Some(Box::new(rhs.clone())); + if *rhs != clean::Term::Type(clean::Type::Tuple(Vec::new())) { + *output = Some(Box::new(rhs.ty().unwrap().clone())); } } }, diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 00c6e38839f..fac1a0817e0 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1212,7 +1212,7 @@ impl Lifetime { crate enum WherePredicate { BoundPredicate { ty: Type, bounds: Vec<GenericBound>, bound_params: Vec<Lifetime> }, RegionPredicate { lifetime: Lifetime, bounds: Vec<GenericBound> }, - EqPredicate { lhs: Type, rhs: Type }, + EqPredicate { lhs: Type, rhs: Term }, } impl WherePredicate { @@ -1308,7 +1308,9 @@ impl FnDecl { FnRetTy::Return(Type::ImplTrait(bounds)) => match &bounds[0] { GenericBound::TraitBound(PolyTrait { trait_, .. }, ..) => { let bindings = trait_.bindings().unwrap(); - FnRetTy::Return(bindings[0].ty().clone()) + let ret_ty = bindings[0].term(); + let ty = ret_ty.ty().expect("Unexpected constant return term"); + FnRetTy::Return(ty.clone()) } _ => panic!("unexpected desugaring of async function"), }, @@ -2122,6 +2124,24 @@ crate struct Constant { } #[derive(Clone, PartialEq, Eq, Hash, Debug)] +crate enum Term { + Type(Type), + Constant(Constant), +} + +impl Term { + crate fn ty(&self) -> Option<&Type> { + if let Term::Type(ty) = self { Some(ty) } else { None } + } +} + +impl From<Type> for Term { + fn from(ty: Type) -> Self { + Term::Type(ty) + } +} + +#[derive(Clone, PartialEq, Eq, Hash, Debug)] crate enum ConstantKind { /// This is the wrapper around `ty::Const` for a non-local constant. Because it doesn't have a /// `BodyId`, we need to handle it on its own. @@ -2283,14 +2303,14 @@ crate struct TypeBinding { #[derive(Clone, PartialEq, Eq, Debug, Hash)] crate enum TypeBindingKind { - Equality { ty: Type }, + Equality { term: Term }, Constraint { bounds: Vec<GenericBound> }, } impl TypeBinding { - crate fn ty(&self) -> &Type { + crate fn term(&self) -> &Term { match self.kind { - TypeBindingKind::Equality { ref ty } => ty, + TypeBindingKind::Equality { ref term } => term, _ => panic!("expected equality type binding for parenthesized generic args"), } } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 8571a6a137f..08840626259 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1442,11 +1442,11 @@ impl clean::TypeBinding { display_fn(move |f| { f.write_str(self.name.as_str())?; match self.kind { - clean::TypeBindingKind::Equality { ref ty } => { + clean::TypeBindingKind::Equality { ref term } => { if f.alternate() { - write!(f, " = {:#}", ty.print(cx))?; + write!(f, " = {:#}", term.print(cx))?; } else { - write!(f, " = {}", ty.print(cx))?; + write!(f, " = {}", term.print(cx))?; } } clean::TypeBindingKind::Constraint { ref bounds } => { @@ -1492,6 +1492,18 @@ impl clean::GenericArg { } } +impl clean::types::Term { + crate fn print<'a, 'tcx: 'a>( + &'a self, + cx: &'a Context<'tcx>, + ) -> impl fmt::Display + 'a + Captures<'tcx> { + match self { + clean::types::Term::Type(ty) => ty.print(cx), + _ => todo!(), + } + } +} + crate fn display_fn(f: impl FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result) -> impl fmt::Display { struct WithFormatter<F>(Cell<Option<F>>); diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index c8efa4bbbcc..e77bd5c9223 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -162,7 +162,7 @@ impl FromWithTcx<clean::TypeBindingKind> for TypeBindingKind { fn from_tcx(kind: clean::TypeBindingKind, tcx: TyCtxt<'_>) -> Self { use clean::TypeBindingKind::*; match kind { - Equality { ty } => TypeBindingKind::Equality(ty.into_tcx(tcx)), + Equality { term } => TypeBindingKind::Equality(term.into_tcx(tcx)), Constraint { bounds } => { TypeBindingKind::Constraint(bounds.into_iter().map(|a| a.into_tcx(tcx)).collect()) } @@ -452,6 +452,15 @@ impl FromWithTcx<clean::Type> for Type { } } +impl FromWithTcx<clean::Term> for Term { + fn from_tcx(term: clean::Term, tcx: TyCtxt<'_>) -> Term { + match term { + clean::Term::Type(ty) => Term::Type(FromWithTcx::from_tcx(ty, tcx)), + clean::Term::Constant(c) => Term::Constant(FromWithTcx::from_tcx(c, tcx)), + } + } +} + impl FromWithTcx<clean::BareFunctionDecl> for FunctionPointer { fn from_tcx(bare_decl: clean::BareFunctionDecl, tcx: TyCtxt<'_>) -> Self { let clean::BareFunctionDecl { unsafety, generic_params, decl, abi } = bare_decl; diff --git a/src/llvm-project b/src/llvm-project -Subproject 2abffbf977a9e8c6ca4174a08fe5c4d7781f0aa +Subproject 6b3dbcc81a470e5da84576d63fcfc19e3b1154c diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index 9466f84ffcd..618c8aab86a 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -148,7 +148,7 @@ pub struct TypeBinding { #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "snake_case")] pub enum TypeBindingKind { - Equality(Type), + Equality(Term), Constraint(Vec<GenericBound>), } @@ -335,7 +335,7 @@ pub enum GenericParamDefKind { pub enum WherePredicate { BoundPredicate { ty: Type, bounds: Vec<GenericBound> }, RegionPredicate { lifetime: String, bounds: Vec<GenericBound> }, - EqPredicate { lhs: Type, rhs: Type }, + EqPredicate { lhs: Type, rhs: Term }, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] @@ -361,6 +361,13 @@ pub enum TraitBoundModifier { #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "snake_case")] +pub enum Term { + Type(Type), + Constant(Constant), +} + +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +#[serde(rename_all = "snake_case")] #[serde(tag = "kind", content = "inner")] pub enum Type { /// Structs, enums, and traits diff --git a/src/test/ui/associated-consts/assoc-const.rs b/src/test/ui/associated-consts/assoc-const.rs new file mode 100644 index 00000000000..cd4b42f9f84 --- /dev/null +++ b/src/test/ui/associated-consts/assoc-const.rs @@ -0,0 +1,21 @@ +#![feature(associated_const_equality)] + +pub trait Foo { + const N: usize; +} + +pub struct Bar; + +impl Foo for Bar { + const N: usize = 3; +} + +const TEST:usize = 3; + + +fn foo<F: Foo<N=3>>() {} +//~^ ERROR associated const equality is incomplete +fn bar<F: Foo<N={TEST}>>() {} +//~^ ERROR associated const equality is incomplete + +fn main() {} diff --git a/src/test/ui/associated-consts/assoc-const.stderr b/src/test/ui/associated-consts/assoc-const.stderr new file mode 100644 index 00000000000..ccaa6fa8ee8 --- /dev/null +++ b/src/test/ui/associated-consts/assoc-const.stderr @@ -0,0 +1,14 @@ +error: associated const equality is incomplete + --> $DIR/assoc-const.rs:16:15 + | +LL | fn foo<F: Foo<N=3>>() {} + | ^^^ cannot yet relate associated const + +error: associated const equality is incomplete + --> $DIR/assoc-const.rs:18:15 + | +LL | fn bar<F: Foo<N={TEST}>>() {} + | ^^^^^^^^ cannot yet relate associated const + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs index 19e0f38d320..b126b24853f 100644 --- a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs @@ -7,8 +7,9 @@ struct Bar; const T: usize = 42; impl Foo<N = 3> for Bar { -//~^ ERROR cannot constrain an associated constant to a value +//~^ ERROR this trait takes 1 generic argument but 0 generic arguments were supplied //~| ERROR associated type bindings are not allowed here +//~| ERROR associated const equality is incomplete fn do_x(&self) -> [u8; 3] { [0u8; 3] } diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr index bbca92ad63a..59ba054aa11 100644 --- a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr @@ -1,11 +1,27 @@ -error: cannot constrain an associated constant to a value +error[E0658]: associated const equality is incomplete --> $DIR/issue-89013-no-kw.rs:9:10 | LL | impl Foo<N = 3> for Bar { - | -^^^- - | | | - | | ...cannot be constrained to this value - | this associated constant... + | ^^^^^ + | + = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information + = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + +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 { + | ^^^ 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 @@ -13,6 +29,7 @@ error[E0229]: associated type bindings are not allowed here LL | impl Foo<N = 3> for Bar { | ^^^^^ associated type not allowed here -error: aborting due to 2 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, E0658. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013.rs b/src/test/ui/const-generics/parser-error-recovery/issue-89013.rs index ca1158a2f6d..9431779faf8 100644 --- a/src/test/ui/const-generics/parser-error-recovery/issue-89013.rs +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013.rs @@ -8,8 +8,9 @@ const T: usize = 42; impl Foo<N = const 3> for Bar { //~^ ERROR expected lifetime, type, or constant, found keyword `const` -//~| ERROR cannot constrain an associated constant to a value +//~| ERROR this trait takes 1 generic //~| ERROR associated type bindings are not allowed here +//~| ERROR associated const equality is incomplete fn do_x(&self) -> [u8; 3] { [0u8; 3] } diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr b/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr index 85379d3f06e..9d473992670 100644 --- a/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr @@ -10,14 +10,30 @@ LL - impl Foo<N = const 3> for Bar { LL + impl Foo<N = 3> for Bar { | -error: cannot constrain an associated constant to a value +error[E0658]: associated const equality is incomplete --> $DIR/issue-89013.rs:9:10 | LL | impl Foo<N = const 3> for Bar { - | -^^^^^^^^^- - | | | - | | ...cannot be constrained to this value - | this associated constant... + | ^^^^^^^^^^^ + | + = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information + = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + +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 { + | ^^^ 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 @@ -25,6 +41,7 @@ error[E0229]: associated type bindings are not allowed here LL | impl Foo<N = const 3> for Bar { | ^^^^^^^^^^^ associated type not allowed here -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0229`. +Some errors have detailed explanations: E0107, E0229, E0658. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/feature-gates/feature-gate-associated_const_equality.rs b/src/test/ui/feature-gates/feature-gate-associated_const_equality.rs new file mode 100644 index 00000000000..b51ead2a188 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-associated_const_equality.rs @@ -0,0 +1,16 @@ +pub trait TraitWAssocConst { + const A: usize; +} +pub struct Demo {} + +impl TraitWAssocConst for Demo { + const A: usize = 32; +} + +fn foo<A: TraitWAssocConst<A=32>>() {} +//~^ ERROR associated const equality +//~| ERROR associated const equality + +fn main() { + foo::<Demo>(); +} diff --git a/src/test/ui/feature-gates/feature-gate-associated_const_equality.stderr b/src/test/ui/feature-gates/feature-gate-associated_const_equality.stderr new file mode 100644 index 00000000000..f4db49c4af8 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-associated_const_equality.stderr @@ -0,0 +1,18 @@ +error[E0658]: associated const equality is incomplete + --> $DIR/feature-gate-associated_const_equality.rs:10:28 + | +LL | fn foo<A: TraitWAssocConst<A=32>>() {} + | ^^^^ + | + = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information + = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + +error: associated const equality is incomplete + --> $DIR/feature-gate-associated_const_equality.rs:10:28 + | +LL | fn foo<A: TraitWAssocConst<A=32>>() {} + | ^^^^ cannot yet relate associated const + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/parser/recover-assoc-const-constraint.rs b/src/test/ui/parser/recover-assoc-const-constraint.rs index 06be3cdcc1a..1453e6cb5cd 100644 --- a/src/test/ui/parser/recover-assoc-const-constraint.rs +++ b/src/test/ui/parser/recover-assoc-const-constraint.rs @@ -1,7 +1,9 @@ #[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>(); + //~^ ERROR associated const equality is incomplete + bar::<Item = { 42 }>(); + //~^ ERROR associated const equality is incomplete } fn main() {} diff --git a/src/test/ui/parser/recover-assoc-const-constraint.stderr b/src/test/ui/parser/recover-assoc-const-constraint.stderr index c6733b33faa..2d36ce4e986 100644 --- a/src/test/ui/parser/recover-assoc-const-constraint.stderr +++ b/src/test/ui/parser/recover-assoc-const-constraint.stderr @@ -1,20 +1,21 @@ -error: cannot constrain an associated constant to a value +error[E0658]: associated const equality is incomplete --> $DIR/recover-assoc-const-constraint.rs:3:11 | LL | bar::<Item = 42>(); - | ----^^^-- - | | | - | | ...cannot be constrained to this value - | this associated constant... + | ^^^^^^^^^ + | + = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information + = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable -error: cannot constrain an associated constant to a value - --> $DIR/recover-assoc-const-constraint.rs:4:11 +error[E0658]: associated const equality is incomplete + --> $DIR/recover-assoc-const-constraint.rs:5:11 | LL | bar::<Item = { 42 }>(); - | ----^^^------ - | | | - | | ...cannot be constrained to this value - | this associated constant... + | ^^^^^^^^^^^^^ + | + = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information + = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/specialization/min_specialization/repeated_projection_type.stderr b/src/test/ui/specialization/min_specialization/repeated_projection_type.stderr index 07d194476a5..ad51707070f 100644 --- a/src/test/ui/specialization/min_specialization/repeated_projection_type.stderr +++ b/src/test/ui/specialization/min_specialization/repeated_projection_type.stderr @@ -1,4 +1,4 @@ -error: cannot specialize on `Binder(ProjectionPredicate(ProjectionTy { substs: [V], item_def_id: DefId(0:6 ~ repeated_projection_type[HASH]::Id::This) }, (I,)), [])` +error: cannot specialize on `Binder(ProjectionPredicate(ProjectionTy { substs: [V], item_def_id: DefId(0:6 ~ repeated_projection_type[HASH]::Id::This) }, Ty((I,))), [])` --> $DIR/repeated_projection_type.rs:19:1 | LL | / impl<I, V: Id<This = (I,)>> X for V { diff --git a/src/tools/cargo b/src/tools/cargo -Subproject 06b9d31743210b788b130c8a484c2838afa6fc2 +Subproject 358e79fe56fe374649275ca7aebaafd57ade0e8 diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs index 86819752f90..2af3555e370 100644 --- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs +++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs @@ -6,7 +6,7 @@ use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::intravisit::FnKind; use rustc_hir::{ - AsyncGeneratorKind, Block, Body, Expr, ExprKind, FnDecl, FnRetTy, GeneratorKind, GenericArg, GenericBound, HirId, + Term, AsyncGeneratorKind, Block, Body, Expr, ExprKind, FnDecl, FnRetTy, GeneratorKind, GenericArg, GenericBound, HirId, IsAsync, ItemKind, LifetimeName, TraitRef, Ty, TyKind, TypeBindingKind, }; use rustc_lint::{LateContext, LateLintPass}; @@ -140,7 +140,7 @@ fn future_output_ty<'tcx>(trait_ref: &'tcx TraitRef<'tcx>) -> Option<&'tcx Ty<'t if args.bindings.len() == 1; let binding = &args.bindings[0]; if binding.ident.name == sym::Output; - if let TypeBindingKind::Equality{ty: output} = binding.kind; + if let TypeBindingKind::Equality{term: Term::Ty(output)} = binding.kind; then { return Some(output) } diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index 7357219f7b4..a9a06c3db75 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -2178,12 +2178,16 @@ impl<'tcx> LateLintPass<'tcx> for Methods { // one of the associated types must be Self for &(predicate, _span) in cx.tcx.explicit_item_bounds(def_id) { if let ty::PredicateKind::Projection(projection_predicate) = predicate.kind().skip_binder() { + let assoc_ty = match projection_predicate.term { + ty::Term::Ty(ty) => ty, + ty::Term::Const(_c) => continue, + }; // 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(assoc_ty, self_adt) { return; } - } else if contains_ty(projection_predicate.ty, self_ty) { + } else if contains_ty(assoc_ty, self_ty) { return; } } diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index e5b6d296b2d..9162de3ccea 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -243,9 +243,10 @@ fn check_other_call_arg<'tcx>( if if trait_predicate.def_id() == deref_trait_id { if let [projection_predicate] = projection_predicates[..] { let normalized_ty = - cx.tcx.subst_and_normalize_erasing_regions(call_substs, cx.param_env, projection_predicate.ty); + cx.tcx.subst_and_normalize_erasing_regions(call_substs, cx.param_env, projection_predicate.term); 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").map_or(false, |ty| ty::Term::Ty(ty) == normalized_ty) } else { false } diff --git a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs index fe35ff33d35..68156df2ece 100644 --- a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs +++ b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs @@ -98,9 +98,10 @@ fn get_args_to_check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Ve if trait_pred.self_ty() == inp; if let Some(return_ty_pred) = get_projection_pred(cx, generics, *trait_pred); then { - if ord_preds.iter().any(|ord| ord.self_ty() == return_ty_pred.ty) { + if ord_preds.iter().any(|ord| Some(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().unwrap()) { args_to_check.push((i, "PartialOrd".to_string())); } } diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index 3d3180521ab..604c95d2bc8 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -645,11 +645,19 @@ pub fn eq_generic_bound(l: &GenericBound, r: &GenericBound) -> bool { } } -pub fn eq_assoc_constraint(l: &AssocTyConstraint, r: &AssocTyConstraint) -> bool { - use AssocTyConstraintKind::*; +fn eq_term(l: &Term, r: &Term) -> bool { + match (l, r) { + (Term::Ty(l), Term::Ty(r)) => eq_ty(l,r), + (Term::Const(l), Term::Const(r)) => eq_anon_const(l,r), + _ => false, + } +} + +pub fn eq_assoc_constraint(l: &AssocConstraint, r: &AssocConstraint) -> bool { + use AssocConstraintKind::*; eq_id(l.ident, r.ident) && match (&l.kind, &r.kind) { - (Equality { ty: l }, Equality { ty: r }) => eq_ty(l, r), + (Equality { term: l }, Equality { term: r }) => eq_term(l, r), (Bound { bounds: l }, Bound { bounds: r }) => over(l, r, eq_generic_bound), _ => false, } diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer -Subproject 0f8c96c92689af8378dbe9f466c6bf15a3a2745 +Subproject 8e9ccbf97a70259b6c6576e8fd7d77d28238737 diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index 88f5dc43245..5de30129266 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -1,7 +1,7 @@ use std::iter::ExactSizeIterator; use std::ops::Deref; -use rustc_ast::ast::{self, FnRetTy, Mutability}; +use rustc_ast::ast::{self, FnRetTy, Mutability, Term}; use rustc_ast::ptr; use rustc_span::{symbol::kw, BytePos, Pos, Span}; @@ -141,7 +141,7 @@ pub(crate) enum SegmentParam<'a> { Const(&'a ast::AnonConst), LifeTime(&'a ast::Lifetime), Type(&'a ast::Ty), - Binding(&'a ast::AssocTyConstraint), + Binding(&'a ast::AssocConstraint), } impl<'a> SegmentParam<'a> { @@ -176,9 +176,9 @@ impl<'a> Rewrite for SegmentParam<'a> { } } -impl Rewrite for ast::AssocTyConstraint { +impl Rewrite for ast::AssocConstraint { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> { - use ast::AssocTyConstraintKind::{Bound, Equality}; + use ast::AssocConstraintKind::{Bound, Equality}; let mut result = String::with_capacity(128); result.push_str(rewrite_ident(context, self.ident)); @@ -206,11 +206,14 @@ impl Rewrite for ast::AssocTyConstraint { } } -impl Rewrite for ast::AssocTyConstraintKind { +impl Rewrite for ast::AssocConstraintKind { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> { match self { - ast::AssocTyConstraintKind::Equality { ty } => ty.rewrite(context, shape), - ast::AssocTyConstraintKind::Bound { bounds } => bounds.rewrite(context, shape), + ast::AssocConstraintKind::Equality { term } => match term { + Term::Ty(ty) => ty.rewrite(context, shape), + Term::Const(c) => c.rewrite(context, shape), + }, + ast::AssocConstraintKind::Bound { bounds } => bounds.rewrite(context, shape), } } } |
