diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2021-11-27 11:46:44 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-11-27 11:46:44 +0100 |
| commit | 7c5bcd548be2d2020c1476346304a1cc64078e2f (patch) | |
| tree | 584a77060ba36a80307abd6c30cf505a118ca3d9 /compiler | |
| parent | 55f8b5f559ffa61434d844de94963af3c2258276 (diff) | |
| parent | 4954389a9dccf2e915a639155b7039f1454acc9c (diff) | |
| download | rust-7c5bcd548be2d2020c1476346304a1cc64078e2f.tar.gz rust-7c5bcd548be2d2020c1476346304a1cc64078e2f.zip | |
Rollup merge of #91208 - estebank:eq-constraint, r=cjgillot
Account for incorrect `where T::Assoc = Ty` bound Provide suggestoin to constrain trait bound for associated type. Revert incorrect changes to `missing-bounds` test. Address part of #20041.
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_ast_passes/src/ast_validation.rs | 49 | ||||
| -rw-r--r-- | compiler/rustc_ast_passes/src/lib.rs | 1 |
2 files changed, 49 insertions, 1 deletions
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 1822ba6ec99..efc30121987 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -23,7 +23,7 @@ use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Span; use rustc_target::spec::abi; use std::mem; -use std::ops::DerefMut; +use std::ops::{Deref, DerefMut}; const MORE_EXTERN: &str = "for more information, visit https://doc.rust-lang.org/std/keyword.extern.html"; @@ -1714,6 +1714,53 @@ fn deny_equality_constraints( } } } + // Given `A: Foo, A::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`. + if let TyKind::Path(None, full_path) = &predicate.lhs_ty.kind { + if let [potential_param, potential_assoc] = &full_path.segments[..] { + for param in &generics.params { + if param.ident == potential_param.ident { + for bound in ¶m.bounds { + if let ast::GenericBound::Trait(trait_ref, TraitBoundModifier::None) = bound + { + if let [trait_segment] = &trait_ref.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 { + continue; + }; + ( + format!(", {} = {}", assoc, ty), + arg.span().shrink_to_hi(), + ) + } + _ => continue, + }, + None => ( + format!("<{} = {}>", assoc, ty), + trait_segment.span().shrink_to_hi(), + ), + }; + err.multipart_suggestion( + &format!( + "if `{}::{}` is an associated type you're trying to set, \ + use the associated type binding syntax", + trait_segment.ident, potential_assoc.ident, + ), + vec![(span, args), (predicate.span, String::new())], + Applicability::MaybeIncorrect, + ); + } + } + } + } + } + } + } err.note( "see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information", ); diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs index 47666670b2b..adc4d117b80 100644 --- a/compiler/rustc_ast_passes/src/lib.rs +++ b/compiler/rustc_ast_passes/src/lib.rs @@ -6,6 +6,7 @@ #![feature(iter_is_partitioned)] #![feature(box_patterns)] +#![feature(let_else)] #![recursion_limit = "256"] pub mod ast_validation; |
