Skip to content

Commit da478ac

Browse files
authored
Merge pull request #1748 from dtolnay/impluse
Reject trait bound containing only precise capture
2 parents 6afa190 + 81f0899 commit da478ac

File tree

1 file changed

+20
-6
lines changed

1 file changed

+20
-6
lines changed

src/ty.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ pub(crate) mod parsing {
290290
TypeReference, TypeSlice, TypeTraitObject, TypeTuple,
291291
};
292292
use crate::verbatim;
293-
use proc_macro2::Span;
293+
use proc_macro2::{Span, TokenTree};
294294

295295
#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
296296
impl Parse for Type {
@@ -859,13 +859,14 @@ pub(crate) mod parsing {
859859
let mut at_least_one_trait = false;
860860
for bound in &bounds {
861861
match bound {
862-
TypeParamBound::Trait(_) | TypeParamBound::Verbatim(_) => {
862+
TypeParamBound::Trait(_) => {
863863
at_least_one_trait = true;
864864
break;
865865
}
866866
TypeParamBound::Lifetime(lifetime) => {
867867
last_lifetime_span = Some(lifetime.ident.span());
868868
}
869+
TypeParamBound::Verbatim(_) => unreachable!(),
869870
}
870871
}
871872
// Just lifetimes like `'a + 'b` is not a TraitObject.
@@ -902,24 +903,37 @@ pub(crate) mod parsing {
902903
allow_precise_capture,
903904
allow_tilde_const,
904905
)?;
905-
let mut last_lifetime_span = None;
906+
let mut last_nontrait_span = None;
906907
let mut at_least_one_trait = false;
907908
for bound in &bounds {
908909
match bound {
909-
TypeParamBound::Trait(_) | TypeParamBound::Verbatim(_) => {
910+
TypeParamBound::Trait(_) => {
910911
at_least_one_trait = true;
911912
break;
912913
}
913914
TypeParamBound::Lifetime(lifetime) => {
914-
last_lifetime_span = Some(lifetime.ident.span());
915+
last_nontrait_span = Some(lifetime.ident.span());
916+
}
917+
TypeParamBound::Verbatim(verbatim) => {
918+
let mut tokens = verbatim.clone().into_iter();
919+
match tokens.next().unwrap() {
920+
TokenTree::Ident(ident) if ident == "use" => {
921+
last_nontrait_span = Some(tokens.last().unwrap().span());
922+
}
923+
_ => {
924+
// ~const Trait
925+
at_least_one_trait = true;
926+
break;
927+
}
928+
}
915929
}
916930
}
917931
}
918932
if !at_least_one_trait {
919933
let msg = "at least one trait must be specified";
920934
return Err(error::new2(
921935
impl_token.span,
922-
last_lifetime_span.unwrap(),
936+
last_nontrait_span.unwrap(),
923937
msg,
924938
));
925939
}

0 commit comments

Comments
 (0)