From 8f32430e5a8875400eb1d0f9d994f58c9a5de75b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Fri, 6 Mar 2026 18:42:32 +0100 Subject: [PATCH] Syntactically reject equality predicates --- compiler/rustc_ast/src/ast.rs | 2 - compiler/rustc_ast_lowering/src/item.rs | 12 -- .../rustc_ast_passes/src/ast_validation.rs | 178 +----------------- compiler/rustc_ast_passes/src/errors.rs | 43 ----- .../rustc_ast_pretty/src/pprust/state/item.rs | 8 - .../src/deriving/coerce_pointee.rs | 3 +- compiler/rustc_hir/src/hir.rs | 4 - compiler/rustc_hir/src/intravisit.rs | 4 - .../src/check/compare_impl_item.rs | 2 - .../src/collect/predicates_of.rs | 4 - .../src/collect/resolve_bound_vars.rs | 6 - compiler/rustc_hir_pretty/src/lib.rs | 8 - compiler/rustc_lint/src/builtin.rs | 1 - compiler/rustc_parse/src/errors.rs | 9 + compiler/rustc_parse/src/parser/generics.rs | 35 ++-- compiler/rustc_passes/src/input_stats.rs | 4 +- src/librustdoc/clean/mod.rs | 11 +- src/librustdoc/clean/simplify.rs | 4 +- src/librustdoc/clean/types.rs | 2 +- src/librustdoc/html/format.rs | 2 +- src/librustdoc/json/conversions.rs | 2 +- .../clippy/clippy_lints/src/lifetimes.rs | 8 - .../src/multiple_bound_locations.rs | 1 - .../clippy/clippy_utils/src/ast_utils/mod.rs | 1 - .../clippy/clippy_utils/src/hir_utils.rs | 3 - src/tools/rustfmt/src/types.rs | 10 - ...pe-projection-from-multiple-supertraits.rs | 2 +- ...rojection-from-multiple-supertraits.stderr | 2 +- .../equality-bound.rs | 18 +- .../equality-bound.stderr | 34 ++-- .../missing-bounds.fixed | 2 +- .../missing-bounds.rs | 2 +- .../missing-bounds.stderr | 4 +- tests/ui/where-clauses/equality-predicates.rs | 25 +++ .../where-clauses/equality-predicates.stderr | 34 ++++ .../where-equality-constraints.rs | 6 - .../where-equality-constraints.stderr | 18 -- 37 files changed, 138 insertions(+), 376 deletions(-) create mode 100644 tests/ui/where-clauses/equality-predicates.rs create mode 100644 tests/ui/where-clauses/equality-predicates.stderr delete mode 100644 tests/ui/where-clauses/where-equality-constraints.rs delete mode 100644 tests/ui/where-clauses/where-equality-constraints.stderr diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index ae4989fcbc6c9..32e14a9018d9c 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -510,8 +510,6 @@ pub enum WherePredicateKind { BoundPredicate(WhereBoundPredicate), /// A lifetime predicate (e.g., `'a: 'b + 'c`). RegionPredicate(WhereRegionPredicate), - /// An equality predicate (unsupported). - EqPredicate(WhereEqPredicate), } /// A type bound. diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 1c80c56f26935..b58d6b9ac0472 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -2052,18 +2052,6 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { in_where_clause: true, }) } - WherePredicateKind::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty }) => { - hir::WherePredicateKind::EqPredicate(hir::WhereEqPredicate { - lhs_ty: self.lower_ty_alloc( - lhs_ty, - ImplTraitContext::Disallowed(ImplTraitPosition::Bound), - ), - rhs_ty: self.lower_ty_alloc( - rhs_ty, - ImplTraitContext::Disallowed(ImplTraitPosition::Bound), - ), - }) - } }); hir::WherePredicate { hir_id, span, kind } } diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 0541d39318f47..32f5cb122b762 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -17,7 +17,6 @@ //! require name resolution or type checking, or other kinds of complex analysis. use std::mem; -use std::ops::{Deref, DerefMut}; use std::str::FromStr; use itertools::{Either, Itertools}; @@ -27,7 +26,7 @@ use rustc_ast::*; use rustc_ast_pretty::pprust::{self, State}; use rustc_attr_parsing::validate_attr; use rustc_data_structures::fx::FxIndexMap; -use rustc_errors::{DiagCtxtHandle, Diagnostic, LintBuffer}; +use rustc_errors::{DiagCtxtHandle, LintBuffer, Diagnostic}; use rustc_feature::Features; use rustc_session::Session; use rustc_session::lint::builtin::{ @@ -37,7 +36,6 @@ use rustc_session::lint::builtin::{ use rustc_session::parse::feature_err; use rustc_span::{Ident, Span, kw, sym}; use rustc_target::spec::{AbiMap, AbiMapping}; -use thin_vec::thin_vec; use crate::errors::{self, TildeConstReason}; @@ -1576,14 +1574,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } validate_generic_param_order(self.dcx(), &generics.params, generics.span); - - for predicate in &generics.where_clause.predicates { - let span = predicate.span; - if let WherePredicateKind::EqPredicate(predicate) = &predicate.kind { - deny_equality_constraints(self, predicate, span, generics); - } - } walk_list!(self, visit_generic_param, &generics.params); + for predicate in &generics.where_clause.predicates { match &predicate.kind { WherePredicateKind::BoundPredicate(bound_pred) => { @@ -1607,7 +1599,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } } - _ => {} + WherePredicateKind::RegionPredicate(_) => {} } self.visit_where_predicate(predicate); } @@ -1939,170 +1931,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } -/// When encountering an equality constraint in a `where` clause, emit an error. If the code seems -/// like it's setting an associated type, provide an appropriate suggestion. -fn deny_equality_constraints( - this: &AstValidator<'_>, - predicate: &WhereEqPredicate, - predicate_span: Span, - generics: &Generics, -) { - let mut err = errors::EqualityInWhere { span: predicate_span, assoc: None, assoc2: None }; - - // Given `::Bar = RhsTy`, suggest `A: Foo`. - if let TyKind::Path(Some(qself), full_path) = &predicate.lhs_ty.kind - && let TyKind::Path(None, path) = &qself.ty.kind - && let [PathSegment { ident, args: None, .. }] = &path.segments[..] - { - for param in &generics.params { - if param.ident == *ident - && let [PathSegment { ident, args, .. }] = &full_path.segments[qself.position..] - { - // Make a new `Path` from `foo::Bar` to `Foo`. - let mut assoc_path = full_path.clone(); - // Remove `Bar` from `Foo::Bar`. - assoc_path.segments.pop(); - let len = assoc_path.segments.len() - 1; - let gen_args = args.as_deref().cloned(); - // Build ``. - let arg = AngleBracketedArg::Constraint(AssocItemConstraint { - id: rustc_ast::node_id::DUMMY_NODE_ID, - ident: *ident, - gen_args, - kind: AssocItemConstraintKind::Equality { - term: predicate.rhs_ty.clone().into(), - }, - span: ident.span, - }); - // Add `` to `Foo`. - match &mut assoc_path.segments[len].args { - Some(args) => match args.deref_mut() { - GenericArgs::Parenthesized(_) | GenericArgs::ParenthesizedElided(..) => { - continue; - } - GenericArgs::AngleBracketed(args) => { - args.args.push(arg); - } - }, - empty_args => { - *empty_args = Some( - AngleBracketedArgs { span: ident.span, args: thin_vec![arg] }.into(), - ); - } - } - err.assoc = Some(errors::AssociatedSuggestion { - span: predicate_span, - ident: *ident, - param: param.ident, - path: pprust::path_to_string(&assoc_path), - }) - } - } - } - - let mut suggest = - |poly: &PolyTraitRef, potential_assoc: &PathSegment, predicate: &WhereEqPredicate| { - if let [trait_segment] = &poly.trait_ref.path.segments[..] { - let assoc = pprust::path_to_string(&ast::Path::from_ident(potential_assoc.ident)); - let ty = pprust::ty_to_string(&predicate.rhs_ty); - let (args, span) = match &trait_segment.args { - Some(args) => match args.deref() { - ast::GenericArgs::AngleBracketed(args) => { - let Some(arg) = args.args.last() else { - return; - }; - (format!(", {assoc} = {ty}"), arg.span().shrink_to_hi()) - } - _ => return, - }, - None => (format!("<{assoc} = {ty}>"), trait_segment.span().shrink_to_hi()), - }; - let removal_span = if generics.where_clause.predicates.len() == 1 { - // We're removing th eonly where bound left, remove the whole thing. - generics.where_clause.span - } else { - let mut span = predicate_span; - let mut prev_span: Option = None; - let mut preds = generics.where_clause.predicates.iter().peekable(); - // Find the predicate that shouldn't have been in the where bound list. - while let Some(pred) = preds.next() { - if let WherePredicateKind::EqPredicate(_) = pred.kind - && pred.span == predicate_span - { - if let Some(next) = preds.peek() { - // This is the first predicate, remove the trailing comma as well. - span = span.with_hi(next.span.lo()); - } else if let Some(prev_span) = prev_span { - // Remove the previous comma as well. - span = span.with_lo(prev_span.hi()); - } - } - prev_span = Some(pred.span); - } - span - }; - err.assoc2 = Some(errors::AssociatedSuggestion2 { - span, - args, - predicate: removal_span, - trait_segment: trait_segment.ident, - potential_assoc: potential_assoc.ident, - }); - } - }; - - if let TyKind::Path(None, full_path) = &predicate.lhs_ty.kind { - // Given `A: Foo, Foo::Bar = RhsTy`, suggest `A: Foo`. - for bounds in generics.params.iter().map(|p| &p.bounds).chain( - generics.where_clause.predicates.iter().filter_map(|pred| match &pred.kind { - WherePredicateKind::BoundPredicate(p) => Some(&p.bounds), - _ => None, - }), - ) { - for bound in bounds { - if let GenericBound::Trait(poly) = bound - && poly.modifiers == TraitBoundModifiers::NONE - { - if full_path.segments[..full_path.segments.len() - 1] - .iter() - .map(|segment| segment.ident.name) - .zip(poly.trait_ref.path.segments.iter().map(|segment| segment.ident.name)) - .all(|(a, b)| a == b) - && let Some(potential_assoc) = full_path.segments.last() - { - suggest(poly, potential_assoc, predicate); - } - } - } - } - // Given `A: Foo, A::Bar = RhsTy`, suggest `A: Foo`. - if let [potential_param, potential_assoc] = &full_path.segments[..] { - for (ident, bounds) in generics.params.iter().map(|p| (p.ident, &p.bounds)).chain( - generics.where_clause.predicates.iter().filter_map(|pred| match &pred.kind { - WherePredicateKind::BoundPredicate(p) - if let ast::TyKind::Path(None, path) = &p.bounded_ty.kind - && let [segment] = &path.segments[..] => - { - Some((segment.ident, &p.bounds)) - } - _ => None, - }), - ) { - if ident == potential_param.ident { - for bound in bounds { - if let ast::GenericBound::Trait(poly) = bound - && poly.modifiers == TraitBoundModifiers::NONE - { - suggest(poly, potential_assoc, predicate); - } - } - } - } - } - } - this.dcx().emit_err(err); -} - pub fn check_crate( sess: &Session, features: &Features, diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index b3a22c0c99549..53b89ec994539 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -879,49 +879,6 @@ pub(crate) struct PatternInBodiless { pub span: Span, } -#[derive(Diagnostic)] -#[diag("equality constraints are not yet supported in `where` clauses")] -#[note("see issue #20041 for more information")] -pub(crate) struct EqualityInWhere { - #[primary_span] - #[label("not supported")] - pub span: Span, - #[subdiagnostic] - pub assoc: Option, - #[subdiagnostic] - pub assoc2: Option, -} - -#[derive(Subdiagnostic)] -#[suggestion( - "if `{$ident}` is an associated type you're trying to set, use the associated type binding syntax", - code = "{param}: {path}", - style = "verbose", - applicability = "maybe-incorrect" -)] -pub(crate) struct AssociatedSuggestion { - #[primary_span] - pub span: Span, - pub ident: Ident, - pub param: Ident, - pub path: String, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion( - "if `{$trait_segment}::{$potential_assoc}` is an associated type you're trying to set, use the associated type binding syntax", - applicability = "maybe-incorrect" -)] -pub(crate) struct AssociatedSuggestion2 { - #[suggestion_part(code = "{args}")] - pub span: Span, - pub args: String, - #[suggestion_part(code = "")] - pub predicate: Span, - pub trait_segment: Ident, - pub potential_assoc: Ident, -} - #[derive(Diagnostic)] #[diag("`#![feature]` may not be used on the {$channel} release channel", code = E0554)] pub(crate) struct FeatureOnNonNightly { diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index 3e9c596148343..0cb2b5a34f1e2 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -833,14 +833,6 @@ impl<'a> State<'a> { self.print_lifetime_bounds(bounds); } } - ast::WherePredicateKind::EqPredicate(ast::WhereEqPredicate { - lhs_ty, rhs_ty, .. - }) => { - self.print_type(lhs_ty); - self.space(); - self.word_space("="); - self.print_type(rhs_ty); - } } } diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs index 1d9551f93a14c..eaf4b638afdab 100644 --- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs +++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs @@ -396,8 +396,7 @@ impl<'a> ast::mut_visit::MutVisitor for TypeSubstitution<'a> { self.visit_param_bound(bound, BoundKind::Bound) } } - rustc_ast::WherePredicateKind::RegionPredicate(_) - | rustc_ast::WherePredicateKind::EqPredicate(_) => {} + rustc_ast::WherePredicateKind::RegionPredicate(_) => {} } } } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 71ef6c9a9c03c..7f5e264e92b48 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1105,8 +1105,6 @@ pub enum WherePredicateKind<'hir> { BoundPredicate(WhereBoundPredicate<'hir>), /// A lifetime predicate (e.g., `'a: 'b + 'c`). RegionPredicate(WhereRegionPredicate<'hir>), - /// An equality predicate (unsupported). - EqPredicate(WhereEqPredicate<'hir>), } impl<'hir> WherePredicateKind<'hir> { @@ -1114,7 +1112,6 @@ impl<'hir> WherePredicateKind<'hir> { match self { WherePredicateKind::BoundPredicate(p) => p.origin == PredicateOrigin::WhereClause, WherePredicateKind::RegionPredicate(p) => p.in_where_clause, - WherePredicateKind::EqPredicate(_) => false, } } @@ -1122,7 +1119,6 @@ impl<'hir> WherePredicateKind<'hir> { match self { WherePredicateKind::BoundPredicate(p) => p.bounds, WherePredicateKind::RegionPredicate(p) => p.bounds, - WherePredicateKind::EqPredicate(_) => &[], } } } diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 25ef56f8b0f2c..edfa76004ee31 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1200,10 +1200,6 @@ pub fn walk_where_predicate<'v, V: Visitor<'v>>( try_visit!(visitor.visit_lifetime(lifetime)); walk_list!(visitor, visit_param_bound, bounds); } - WherePredicateKind::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty }) => { - try_visit!(visitor.visit_ty_unambig(lhs_ty)); - try_visit!(visitor.visit_ty_unambig(rhs_ty)); - } } V::Result::output() } diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index c4ec27e07124f..eeb964241aea8 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1194,7 +1194,6 @@ pub(super) fn check_number_of_early_bound_regions<'tcx>( } } } - _ => {} } } if let Some(impl_node) = tcx.hir_get_if_local(impl_def_id.into()) @@ -1217,7 +1216,6 @@ pub(super) fn check_number_of_early_bound_regions<'tcx>( } } } - _ => {} } } if impl_bounds == bounds_span.len() { diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 30b1bf411687e..678b0f9f995a8 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -315,10 +315,6 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen (pred, span) })) } - - hir::WherePredicateKind::EqPredicate(..) => { - // FIXME(#20041) - } } } diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 4312d5fa9dddf..7334b5dc31edf 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -997,12 +997,6 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { self.visit_lifetime(lifetime); walk_list!(self, visit_param_bound, bounds); } - &hir::WherePredicateKind::EqPredicate(hir::WhereEqPredicate { - lhs_ty, rhs_ty, .. - }) => { - self.visit_ty_unambig(lhs_ty); - self.visit_ty_unambig(rhs_ty); - } } } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 82540a9327410..c896f3cee7716 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -2527,14 +2527,6 @@ impl<'a> State<'a> { } } } - hir::WherePredicateKind::EqPredicate(hir::WhereEqPredicate { - lhs_ty, rhs_ty, .. - }) => { - self.print_type(lhs_ty); - self.space(); - self.word_space("="); - self.print_type(rhs_ty); - } } } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index b49a6e261d73d..1eaf55f361e7b 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2143,7 +2143,6 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { } } } - _ => continue, }; if relevant_lifetimes.is_empty() { continue; diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 6faaafcc01005..c02d50da589fc 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -4611,3 +4611,12 @@ pub(crate) struct ReservedMultihashLint { )] pub suggestion: Span, } + +#[derive(Diagnostic)] +#[diag("equality constraints are not supported in where-clauses")] +#[note("see issue #20041 for more information")] +pub(crate) struct EqualityConstraintInWhereClause { + #[primary_span] + #[label("not supported")] + pub span: Span, +} diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index 8c02092fd6788..9f9ba31a44adf 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -581,25 +581,38 @@ impl<'a> Parser<'a> { // * `for<'a> for<'b> Trait1<'a, 'b>: Trait2<'a /* ok */, 'b /* not ok */>` let (bound_vars, _) = self.parse_higher_ranked_binder()?; - // Parse type with mandatory colon and (possibly empty) bounds, - // or with mandatory equality sign and the second type. let ty = self.parse_ty_for_where_clause()?; + if self.eat(exp!(Colon)) { + // The bounds may be empty; we intentionally accept predicates like `Ty:`. let bounds = self.parse_generic_bounds()?; - Ok(ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate { + + return Ok(ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate { bound_generic_params: bound_vars, bounded_ty: ty, bounds, - })) - // FIXME: Decide what should be used here, `=` or `==`. - // FIXME: We are just dropping the binders in lifetime_defs on the floor here. - } else if self.eat(exp!(Eq)) || self.eat(exp!(EqEq)) { + })); + } + + // NOTE: If we ever end up impl'ing and stabilizing equality predicates, + // we need to pick between `=` and `==`, both is not an option! + if self.eat(exp!(Eq)) || self.eat(exp!(EqEq)) { let rhs_ty = self.parse_ty()?; - Ok(ast::WherePredicateKind::EqPredicate(ast::WhereEqPredicate { lhs_ty: ty, rhs_ty })) - } else { - self.maybe_recover_bounds_doubled_colon(&ty)?; - self.unexpected_any() + + // NOTE: If we ever end up impl'ing equality predicates, + // we ought to track the binder in the AST node! + let _ = bound_vars; + + let span = ty.span.to(rhs_ty.span); + let diag = self.dcx().create_err(errors::EqualityConstraintInWhereClause { span }); + // FIXME(fmease): Register a gated span instead that always leads to a hard error? + // Is that necessary for ensuring that it never gets treated as a + // "soft failure" when it comes to MBE matching? + return Err(diag); } + + self.maybe_recover_bounds_doubled_colon(&ty)?; + self.unexpected_any() } pub(super) fn choose_generics_over_qpath(&self, start: usize) -> bool { diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs index e424cc09fb607..b6677b992f400 100644 --- a/compiler/rustc_passes/src/input_stats.rs +++ b/compiler/rustc_passes/src/input_stats.rs @@ -430,7 +430,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { fn visit_where_predicate(&mut self, p: &'v hir::WherePredicate<'v>) { record_variants!( (self, p, p.kind, Some(p.hir_id), hir, WherePredicate, WherePredicateKind), - [BoundPredicate, RegionPredicate, EqPredicate] + [BoundPredicate, RegionPredicate] ); hir_visit::walk_where_predicate(self, p) } @@ -705,7 +705,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { fn visit_where_predicate(&mut self, p: &'v ast::WherePredicate) { record_variants!( (self, p, &p.kind, None, ast, WherePredicate, WherePredicateKind), - [BoundPredicate, RegionPredicate, EqPredicate] + [BoundPredicate, RegionPredicate] ); ast_visit::walk_where_predicate(self, p) } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 2d0ce4f56c65f..d947988d50286 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -405,15 +405,10 @@ fn clean_where_predicate<'tcx>( bound_params, } } - hir::WherePredicateKind::RegionPredicate(wrp) => WherePredicate::RegionPredicate { lifetime: clean_lifetime(wrp.lifetime, cx), bounds: wrp.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(), }, - - // We should never actually reach this case because these predicates should've already been - // rejected in an earlier compiler pass. This feature isn't fully implemented (#20041). - hir::WherePredicateKind::EqPredicate(_) => bug!("EqPredicate"), }) } @@ -518,7 +513,7 @@ fn clean_projection_predicate<'tcx>( pred: ty::Binder<'tcx, ty::ProjectionPredicate<'tcx>>, cx: &mut DocContext<'tcx>, ) -> WherePredicate { - WherePredicate::EqPredicate { + WherePredicate::ProjectionPredicate { lhs: clean_projection(pred.map_bound(|p| p.projection_term), cx, None), rhs: clean_middle_term(pred.map_bound(|p| p.term), cx), } @@ -777,8 +772,8 @@ pub(crate) fn clean_generics<'tcx>( } } } - WherePredicate::EqPredicate { lhs, rhs } => { - eq_predicates.push(WherePredicate::EqPredicate { lhs, rhs }); + WherePredicate::ProjectionPredicate { lhs, rhs } => { + eq_predicates.push(WherePredicate::ProjectionPredicate { lhs, rhs }); } } } diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index 154f31e89dbff..6ab7a699126ec 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -40,7 +40,7 @@ pub(crate) fn where_clauses(tcx: TyCtxt<'_>, clauses: ThinVec) -> ThinVec { lifetimes.push((lifetime, bounds)); } - WP::EqPredicate { lhs, rhs } => equalities.push((lhs, rhs)), + WP::ProjectionPredicate { lhs, rhs } => equalities.push((lhs, rhs)), } } @@ -61,7 +61,7 @@ pub(crate) fn where_clauses(tcx: TyCtxt<'_>, clauses: ThinVec) -> ThinVec, bound_params: Vec }, RegionPredicate { lifetime: Lifetime, bounds: Vec }, - EqPredicate { lhs: QPathData, rhs: Term }, + ProjectionPredicate { lhs: QPathData, rhs: Term }, } impl WherePredicate { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 7eff0b5402b48..c4c9cc643ec7a 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -140,7 +140,7 @@ fn print_where_predicate(predicate: &clean::WherePredicate, cx: &Context<'_>) -> } Ok(()) } - clean::WherePredicate::EqPredicate { lhs, rhs } => { + clean::WherePredicate::ProjectionPredicate { lhs, rhs } => { let opts = WithOpts::from(f); write!( f, diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 5d1f4778f1c52..e2a3d73ed5ba3 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -496,7 +496,7 @@ impl FromClean for WherePredicate { }) .collect(), }, - EqPredicate { lhs, rhs } => WherePredicate::EqPredicate { + ProjectionPredicate { lhs, rhs } => WherePredicate::EqPredicate { // The LHS currently has type `Type` but it should be a `QualifiedPath` since it may // refer to an associated const. However, `EqPredicate` shouldn't exist in the first // place: . diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs index 0bb4992cf6bb4..e6ea9902a2fda 100644 --- a/src/tools/clippy/clippy_lints/src/lifetimes.rs +++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs @@ -551,14 +551,6 @@ fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, generics: &'tcx Generics<'_ } } }, - WherePredicateKind::EqPredicate(ref pred) => { - let mut visitor = RefVisitor::new(cx); - walk_unambig_ty(&mut visitor, pred.lhs_ty); - walk_unambig_ty(&mut visitor, pred.rhs_ty); - if !visitor.lts.is_empty() { - return true; - } - }, } } false diff --git a/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs b/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs index 5b6b4f112455a..8b02c4865d138 100644 --- a/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs +++ b/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs @@ -69,7 +69,6 @@ impl EarlyLintPass for MultipleBoundLocations { emit_lint(cx, *bound_span, pred.lifetime.ident.span); } }, - WherePredicateKind::EqPredicate(_) => {}, } } } diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs index cfff7da60a6a4..e2f81e5b7dc46 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs @@ -781,7 +781,6 @@ pub fn eq_where_predicate(l: &WherePredicate, r: &WherePredicate) -> bool { (RegionPredicate(l), RegionPredicate(r)) => { eq_id(l.lifetime.ident, r.lifetime.ident) && over(&l.bounds, &r.bounds, eq_generic_bound) }, - (EqPredicate(l), EqPredicate(r)) => eq_ty(&l.lhs_ty, &r.lhs_ty) && eq_ty(&l.rhs_ty, &r.rhs_ty), _ => false, } } diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index a4d8fd20e4d3f..5b37ed2d9792a 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -279,9 +279,6 @@ impl HirEqInterExpr<'_, '_, '_> { Self::eq_lifetime(l_region.lifetime, r_region.lifetime) && self.eq_generics_bound(l_region.bounds, r_region.bounds) }, - (WherePredicateKind::EqPredicate(l_eq), WherePredicateKind::EqPredicate(r_eq)) => { - self.eq_ty(l_eq.lhs_ty, r_eq.lhs_ty) - }, _ => false, }) } diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index e574a9d278265..2dfb5e5b28f61 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -484,16 +484,6 @@ impl Rewrite for ast::WherePredicate { ref lifetime, ref bounds, }) => rewrite_bounded_lifetime(lifetime, bounds, self.span, context, shape)?, - ast::WherePredicateKind::EqPredicate(ast::WhereEqPredicate { - ref lhs_ty, - ref rhs_ty, - .. - }) => { - let lhs_ty_str = lhs_ty - .rewrite_result(context, shape) - .map(|lhs| lhs + " =")?; - rewrite_assign_rhs(context, lhs_ty_str, &**rhs_ty, &RhsAssignKind::Ty, shape)? - } }; let mut result = String::with_capacity(attrs_str.len() + pred_str.len() + 1); diff --git a/tests/ui/associated-types/associated-type-projection-from-multiple-supertraits.rs b/tests/ui/associated-types/associated-type-projection-from-multiple-supertraits.rs index b757521e0a452..be42c545ddd9e 100644 --- a/tests/ui/associated-types/associated-type-projection-from-multiple-supertraits.rs +++ b/tests/ui/associated-types/associated-type-projection-from-multiple-supertraits.rs @@ -31,7 +31,7 @@ fn paint(c: C, d: C::Color) { fn dent_object_2(c: &dyn BoxCar) where ::Color = COLOR { //~^ ERROR the value of the associated types - //~| ERROR equality constraints are not yet supported in `where` clauses + //~| ERROR equality constraints are not supported in where-clauses } fn dent_object_3(c: X) diff --git a/tests/ui/associated-types/associated-type-projection-from-multiple-supertraits.stderr b/tests/ui/associated-types/associated-type-projection-from-multiple-supertraits.stderr index 063623ebd123f..280b4730bbb81 100644 --- a/tests/ui/associated-types/associated-type-projection-from-multiple-supertraits.stderr +++ b/tests/ui/associated-types/associated-type-projection-from-multiple-supertraits.stderr @@ -1,4 +1,4 @@ -error: equality constraints are not yet supported in `where` clauses +error: equality constraints are not supported in where-clauses --> $DIR/associated-type-projection-from-multiple-supertraits.rs:32:47 | LL | fn dent_object_2(c: &dyn BoxCar) where ::Color = COLOR { diff --git a/tests/ui/generic-associated-types/equality-bound.rs b/tests/ui/generic-associated-types/equality-bound.rs index c136a6d4bdf2e..77d00b148d269 100644 --- a/tests/ui/generic-associated-types/equality-bound.rs +++ b/tests/ui/generic-associated-types/equality-bound.rs @@ -1,13 +1,13 @@ fn sum>(i: I) -> i32 where I::Item = i32 { -//~^ ERROR equality constraints are not yet supported in `where` clauses +//~^ ERROR equality constraints are not supported in where-clauses panic!() } fn sum2(i: I) -> i32 where I::Item = i32 { -//~^ ERROR equality constraints are not yet supported in `where` clauses +//~^ ERROR equality constraints are not supported in where-clauses panic!() } fn sum3(i: J) -> i32 where I::Item = i32 { -//~^ ERROR equality constraints are not yet supported in `where` clauses +//~^ ERROR equality constraints are not supported in where-clauses //~| ERROR cannot find type `I` panic!() } @@ -18,7 +18,7 @@ struct X {} impl FromIterator for X { fn from_iter(_: T) -> Self where T: IntoIterator, IntoIterator::Item = A, - //~^ ERROR equality constraints are not yet supported in `where` clauses + //~^ ERROR equality constraints are not supported in where-clauses //~| ERROR cannot find type `A` in this scope { todo!() @@ -29,7 +29,7 @@ struct Y {} impl FromIterator for Y { fn from_iter(_: T) -> Self where T: IntoIterator, T::Item = A, - //~^ ERROR equality constraints are not yet supported in `where` clauses + //~^ ERROR equality constraints are not supported in where-clauses //~| ERROR cannot find type `A` in this scope { todo!() @@ -40,7 +40,7 @@ struct Z {} impl FromIterator for Z { fn from_iter(_: T) -> Self where IntoIterator::Item = A, - //~^ ERROR equality constraints are not yet supported in `where` clauses + //~^ ERROR equality constraints are not supported in where-clauses //~| ERROR cannot find type `A` in this scope { todo!() @@ -51,7 +51,7 @@ struct K {} impl FromIterator for K { fn from_iter(_: T) -> Self where T::Item = A, - //~^ ERROR equality constraints are not yet supported in `where` clauses + //~^ ERROR equality constraints are not supported in where-clauses //~| ERROR cannot find type `A` in this scope { todo!() @@ -62,7 +62,7 @@ struct L {} impl FromIterator for L { fn from_iter(_: T) -> Self where IntoIterator::Item = A, T: IntoIterator, - //~^ ERROR equality constraints are not yet supported in `where` clauses + //~^ ERROR equality constraints are not supported in where-clauses //~| ERROR cannot find type `A` in this scope { todo!() @@ -73,7 +73,7 @@ struct M {} impl FromIterator for M { fn from_iter(_: T) -> Self where T::Item = A, T: IntoIterator, - //~^ ERROR equality constraints are not yet supported in `where` clauses + //~^ ERROR equality constraints are not supported in where-clauses //~| ERROR cannot find type `A` in this scope { todo!() diff --git a/tests/ui/generic-associated-types/equality-bound.stderr b/tests/ui/generic-associated-types/equality-bound.stderr index 0ceb5e329ab3a..8f8a316b9b4b4 100644 --- a/tests/ui/generic-associated-types/equality-bound.stderr +++ b/tests/ui/generic-associated-types/equality-bound.stderr @@ -1,30 +1,30 @@ -error: equality constraints are not yet supported in `where` clauses +error: equality constraints are not supported in where-clauses --> $DIR/equality-bound.rs:1:51 | LL | fn sum>(i: I) -> i32 where I::Item = i32 { | ^^^^^^^^^^^^^ not supported | = note: see issue #20041 for more information -help: if `Iterator::Item` is an associated type you're trying to set, use the associated type binding syntax +help: use the associated type binding syntax if `Iterator::Item` is an associated type you're trying to set | LL - fn sum>(i: I) -> i32 where I::Item = i32 { LL + fn sum>(i: I) -> i32 { | -error: equality constraints are not yet supported in `where` clauses +error: equality constraints are not supported in where-clauses --> $DIR/equality-bound.rs:5:41 | LL | fn sum2(i: I) -> i32 where I::Item = i32 { | ^^^^^^^^^^^^^ not supported | = note: see issue #20041 for more information -help: if `Iterator::Item` is an associated type you're trying to set, use the associated type binding syntax +help: use the associated type binding syntax if `Iterator::Item` is an associated type you're trying to set | LL - fn sum2(i: I) -> i32 where I::Item = i32 { LL + fn sum2>(i: I) -> i32 { | -error: equality constraints are not yet supported in `where` clauses +error: equality constraints are not supported in where-clauses --> $DIR/equality-bound.rs:9:41 | LL | fn sum3(i: J) -> i32 where I::Item = i32 { @@ -32,79 +32,79 @@ LL | fn sum3(i: J) -> i32 where I::Item = i32 { | = note: see issue #20041 for more information -error: equality constraints are not yet supported in `where` clauses +error: equality constraints are not supported in where-clauses --> $DIR/equality-bound.rs:20:58 | LL | fn from_iter(_: T) -> Self where T: IntoIterator, IntoIterator::Item = A, | ^^^^^^^^^^^^^^^^^^^^^^ not supported | = note: see issue #20041 for more information -help: if `IntoIterator::Item` is an associated type you're trying to set, use the associated type binding syntax +help: use the associated type binding syntax if `IntoIterator::Item` is an associated type you're trying to set | LL - fn from_iter(_: T) -> Self where T: IntoIterator, IntoIterator::Item = A, LL + fn from_iter(_: T) -> Self where T: IntoIterator, | -error: equality constraints are not yet supported in `where` clauses +error: equality constraints are not supported in where-clauses --> $DIR/equality-bound.rs:31:58 | LL | fn from_iter(_: T) -> Self where T: IntoIterator, T::Item = A, | ^^^^^^^^^^^ not supported | = note: see issue #20041 for more information -help: if `IntoIterator::Item` is an associated type you're trying to set, use the associated type binding syntax +help: use the associated type binding syntax if `IntoIterator::Item` is an associated type you're trying to set | LL - fn from_iter(_: T) -> Self where T: IntoIterator, T::Item = A, LL + fn from_iter(_: T) -> Self where T: IntoIterator, | -error: equality constraints are not yet supported in `where` clauses +error: equality constraints are not supported in where-clauses --> $DIR/equality-bound.rs:42:55 | LL | fn from_iter(_: T) -> Self where IntoIterator::Item = A, | ^^^^^^^^^^^^^^^^^^^^^^ not supported | = note: see issue #20041 for more information -help: if `IntoIterator::Item` is an associated type you're trying to set, use the associated type binding syntax +help: use the associated type binding syntax if `IntoIterator::Item` is an associated type you're trying to set | LL - fn from_iter(_: T) -> Self where IntoIterator::Item = A, LL + fn from_iter>(_: T) -> Self | -error: equality constraints are not yet supported in `where` clauses +error: equality constraints are not supported in where-clauses --> $DIR/equality-bound.rs:53:55 | LL | fn from_iter(_: T) -> Self where T::Item = A, | ^^^^^^^^^^^ not supported | = note: see issue #20041 for more information -help: if `IntoIterator::Item` is an associated type you're trying to set, use the associated type binding syntax +help: use the associated type binding syntax if `IntoIterator::Item` is an associated type you're trying to set | LL - fn from_iter(_: T) -> Self where T::Item = A, LL + fn from_iter>(_: T) -> Self | -error: equality constraints are not yet supported in `where` clauses +error: equality constraints are not supported in where-clauses --> $DIR/equality-bound.rs:64:41 | LL | fn from_iter(_: T) -> Self where IntoIterator::Item = A, T: IntoIterator, | ^^^^^^^^^^^^^^^^^^^^^^ not supported | = note: see issue #20041 for more information -help: if `IntoIterator::Item` is an associated type you're trying to set, use the associated type binding syntax +help: use the associated type binding syntax if `IntoIterator::Item` is an associated type you're trying to set | LL - fn from_iter(_: T) -> Self where IntoIterator::Item = A, T: IntoIterator, LL + fn from_iter(_: T) -> Self where T: IntoIterator, | -error: equality constraints are not yet supported in `where` clauses +error: equality constraints are not supported in where-clauses --> $DIR/equality-bound.rs:75:41 | LL | fn from_iter(_: T) -> Self where T::Item = A, T: IntoIterator, | ^^^^^^^^^^^ not supported | = note: see issue #20041 for more information -help: if `IntoIterator::Item` is an associated type you're trying to set, use the associated type binding syntax +help: use the associated type binding syntax if `IntoIterator::Item` is an associated type you're trying to set | LL - fn from_iter(_: T) -> Self where T::Item = A, T: IntoIterator, LL + fn from_iter(_: T) -> Self where T: IntoIterator, diff --git a/tests/ui/generic-associated-types/missing-bounds.fixed b/tests/ui/generic-associated-types/missing-bounds.fixed index 15cdd44d7f1f9..cd2e1a0ab285e 100644 --- a/tests/ui/generic-associated-types/missing-bounds.fixed +++ b/tests/ui/generic-associated-types/missing-bounds.fixed @@ -37,7 +37,7 @@ impl> Add for D { struct E(B); impl> Add for E where B: Add { - //~^ ERROR equality constraints are not yet supported in `where` clauses + //~^ ERROR equality constraints are not supported in where-clauses type Output = Self; fn add(self, rhs: Self) -> Self { diff --git a/tests/ui/generic-associated-types/missing-bounds.rs b/tests/ui/generic-associated-types/missing-bounds.rs index dad111c8c15cf..41969a16c1e36 100644 --- a/tests/ui/generic-associated-types/missing-bounds.rs +++ b/tests/ui/generic-associated-types/missing-bounds.rs @@ -37,7 +37,7 @@ impl Add for D { struct E(B); impl Add for E where ::Output = B { - //~^ ERROR equality constraints are not yet supported in `where` clauses + //~^ ERROR equality constraints are not supported in where-clauses type Output = Self; fn add(self, rhs: Self) -> Self { diff --git a/tests/ui/generic-associated-types/missing-bounds.stderr b/tests/ui/generic-associated-types/missing-bounds.stderr index 97b88c26e3b38..63e6defe364ac 100644 --- a/tests/ui/generic-associated-types/missing-bounds.stderr +++ b/tests/ui/generic-associated-types/missing-bounds.stderr @@ -1,11 +1,11 @@ -error: equality constraints are not yet supported in `where` clauses +error: equality constraints are not supported in where-clauses --> $DIR/missing-bounds.rs:39:33 | LL | impl Add for E where ::Output = B { | ^^^^^^^^^^^^^^^^^^^^^^ not supported | = note: see issue #20041 for more information -help: if `Output` is an associated type you're trying to set, use the associated type binding syntax +help: use the associated type binding syntax if `Output` is an associated type you're trying to set | LL - impl Add for E where ::Output = B { LL + impl Add for E where B: Add { diff --git a/tests/ui/where-clauses/equality-predicates.rs b/tests/ui/where-clauses/equality-predicates.rs new file mode 100644 index 0000000000000..a3b16f0969a20 --- /dev/null +++ b/tests/ui/where-clauses/equality-predicates.rs @@ -0,0 +1,25 @@ +// Check that equality predicates get rejected. +// In the future we might support these or at least a restricted form of them +// where the LHS is a qpath. Presently however, type checking isn't impl'ed. +// +// See also: . + +fn f() where u8 = u16 {} +//~^ ERROR equality constraints are not supported in where-clauses + +fn g() where for<'a> &'static (u8,) == u16, {} +//~^ ERROR equality constraints are not supported in where-clauses + +// Ensure that they're not just semantically invalid but also syntactically! +// This allows us to change the syntax all we like (we still need to decide +// between `=` and `==` for example) or even remove it entirely. +#[cfg(false)] +fn h() +where + T::Item = fn(), +//~^ ERROR equality constraints are not supported in where-clauses + ::Item == for<> fn(), +//~^ ERROR equality constraints are not supported in where-clauses +{} + +fn main() {} diff --git a/tests/ui/where-clauses/equality-predicates.stderr b/tests/ui/where-clauses/equality-predicates.stderr new file mode 100644 index 0000000000000..07beae23bd150 --- /dev/null +++ b/tests/ui/where-clauses/equality-predicates.stderr @@ -0,0 +1,34 @@ +error: equality constraints are not supported in where-clauses + --> $DIR/equality-predicates.rs:7:14 + | +LL | fn f() where u8 = u16 {} + | ^^^^^^^^ not supported + | + = note: see issue #20041 for more information + +error: equality constraints are not supported in where-clauses + --> $DIR/equality-predicates.rs:10:22 + | +LL | fn g() where for<'a> &'static (u8,) == u16, {} + | ^^^^^^^^^^^^^^^^^^^^^ not supported + | + = note: see issue #20041 for more information + +error: equality constraints are not supported in where-clauses + --> $DIR/equality-predicates.rs:21:5 + | +LL | ::Item == for<> fn(), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not supported + | + = note: see issue #20041 for more information + +error: equality constraints are not supported in where-clauses + --> $DIR/equality-predicates.rs:19:5 + | +LL | T::Item = fn(), + | ^^^^^^^^^^^^^^ not supported + | + = note: see issue #20041 for more information + +error: aborting due to 4 previous errors + diff --git a/tests/ui/where-clauses/where-equality-constraints.rs b/tests/ui/where-clauses/where-equality-constraints.rs deleted file mode 100644 index 8828f09d92d33..0000000000000 --- a/tests/ui/where-clauses/where-equality-constraints.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn f() where u8 = u16 {} -//~^ ERROR equality constraints are not yet supported in `where` clauses -fn g() where for<'a> &'static (u8,) == u16, {} -//~^ ERROR equality constraints are not yet supported in `where` clauses - -fn main() {} diff --git a/tests/ui/where-clauses/where-equality-constraints.stderr b/tests/ui/where-clauses/where-equality-constraints.stderr deleted file mode 100644 index 9d8fac02ed33b..0000000000000 --- a/tests/ui/where-clauses/where-equality-constraints.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error: equality constraints are not yet supported in `where` clauses - --> $DIR/where-equality-constraints.rs:1:14 - | -LL | fn f() where u8 = u16 {} - | ^^^^^^^^ not supported - | - = note: see issue #20041 for more information - -error: equality constraints are not yet supported in `where` clauses - --> $DIR/where-equality-constraints.rs:3:14 - | -LL | fn g() where for<'a> &'static (u8,) == u16, {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not supported - | - = note: see issue #20041 for more information - -error: aborting due to 2 previous errors -