Auto merge of #119384 - matthiaskrgr:rollup-hhz9ws0, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #119331 (rustdoc-search: count path edits with separate edit limit) - #119359 (Simplify Parser::ident_or_error) - #119376 (Add regression test for #106630) - #119379 (Update `parse_seq` doc) - #119380 (Don't suggest writing a bodyless arm if the pattern can never be a never pattern) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
3ee6710954
@ -2937,7 +2937,13 @@ pub(super) fn parse_arm(&mut self) -> PResult<'a, Arm> {
|
||||
let is_almost_fat_arrow = TokenKind::FatArrow
|
||||
.similar_tokens()
|
||||
.is_some_and(|similar_tokens| similar_tokens.contains(&this.token.kind));
|
||||
let mut result = if !is_fat_arrow && !is_almost_fat_arrow {
|
||||
|
||||
// this avoids the compiler saying that a `,` or `}` was expected even though
|
||||
// the pattern isn't a never pattern (and thus an arm body is required)
|
||||
let armless = (!is_fat_arrow && !is_almost_fat_arrow && pat.could_be_never_pattern())
|
||||
|| matches!(this.token.kind, token::Comma | token::CloseDelim(Delimiter::Brace));
|
||||
|
||||
let mut result = if armless {
|
||||
// A pattern without a body, allowed for never patterns.
|
||||
arm_body = None;
|
||||
this.expect_one_of(&[token::Comma], &[token::CloseDelim(Delimiter::Brace)]).map(
|
||||
|
@ -320,9 +320,15 @@ fn to_string(&self) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
/// Used by [`Parser::expect_any_with_type`].
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
enum TokenExpectType {
|
||||
/// Unencountered tokens are inserted into [`Parser::expected_tokens`].
|
||||
/// See [`Parser::check`].
|
||||
Expect,
|
||||
|
||||
/// Unencountered tokens are not inserted into [`Parser::expected_tokens`].
|
||||
/// See [`Parser::check_noexpect`].
|
||||
NoExpect,
|
||||
}
|
||||
|
||||
@ -504,18 +510,10 @@ fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, Ident> {
|
||||
}
|
||||
|
||||
fn ident_or_err(&mut self, recover: bool) -> PResult<'a, (Ident, /* is_raw */ bool)> {
|
||||
let result = self.token.ident().ok_or_else(|| self.expected_ident_found(recover));
|
||||
|
||||
let (ident, is_raw) = match result {
|
||||
Ok(ident) => ident,
|
||||
Err(err) => match err {
|
||||
// we recovered!
|
||||
Ok(ident) => ident,
|
||||
Err(err) => return Err(err),
|
||||
},
|
||||
};
|
||||
|
||||
Ok((ident, is_raw))
|
||||
match self.token.ident() {
|
||||
Some(ident) => Ok(ident),
|
||||
None => self.expected_ident_found(recover),
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if the next token is `tok`, and returns `true` if so.
|
||||
@ -766,13 +764,17 @@ fn expect_gt(&mut self) -> PResult<'a, ()> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if the next token is contained within `kets`, and returns `true` if so.
|
||||
fn expect_any_with_type(&mut self, kets: &[&TokenKind], expect: TokenExpectType) -> bool {
|
||||
kets.iter().any(|k| match expect {
|
||||
TokenExpectType::Expect => self.check(k),
|
||||
TokenExpectType::NoExpect => self.token == **k,
|
||||
TokenExpectType::NoExpect => self.check_noexpect(k),
|
||||
})
|
||||
}
|
||||
|
||||
/// Parses a sequence until the specified delimiters. The function
|
||||
/// `f` must consume tokens until reaching the next separator or
|
||||
/// closing bracket.
|
||||
fn parse_seq_to_before_tokens<T>(
|
||||
&mut self,
|
||||
kets: &[&TokenKind],
|
||||
@ -791,13 +793,15 @@ fn parse_seq_to_before_tokens<T>(
|
||||
}
|
||||
if let Some(t) = &sep.sep {
|
||||
if first {
|
||||
// no separator for the first element
|
||||
first = false;
|
||||
} else {
|
||||
// check for separator
|
||||
match self.expect(t) {
|
||||
Ok(false) => {
|
||||
Ok(false) /* not recovered */ => {
|
||||
self.current_closure.take();
|
||||
}
|
||||
Ok(true) => {
|
||||
Ok(true) /* recovered */ => {
|
||||
self.current_closure.take();
|
||||
recovered = true;
|
||||
break;
|
||||
@ -965,7 +969,7 @@ fn recover_missing_braces_around_closure_body(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Parses a sequence, not including the closing delimiter. The function
|
||||
/// Parses a sequence, not including the delimiters. The function
|
||||
/// `f` must consume tokens until reaching the next separator or
|
||||
/// closing bracket.
|
||||
fn parse_seq_to_before_end<T>(
|
||||
@ -973,11 +977,11 @@ fn parse_seq_to_before_end<T>(
|
||||
ket: &TokenKind,
|
||||
sep: SeqSep,
|
||||
f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>,
|
||||
) -> PResult<'a, (ThinVec<T>, bool, bool)> {
|
||||
) -> PResult<'a, (ThinVec<T>, bool /* trailing */, bool /* recovered */)> {
|
||||
self.parse_seq_to_before_tokens(&[ket], sep, TokenExpectType::Expect, f)
|
||||
}
|
||||
|
||||
/// Parses a sequence, including the closing delimiter. The function
|
||||
/// Parses a sequence, including only the closing delimiter. The function
|
||||
/// `f` must consume tokens until reaching the next separator or
|
||||
/// closing bracket.
|
||||
fn parse_seq_to_end<T>(
|
||||
@ -993,7 +997,7 @@ fn parse_seq_to_end<T>(
|
||||
Ok((val, trailing))
|
||||
}
|
||||
|
||||
/// Parses a sequence, including the closing delimiter. The function
|
||||
/// Parses a sequence, including both delimiters. The function
|
||||
/// `f` must consume tokens until reaching the next separator or
|
||||
/// closing bracket.
|
||||
fn parse_unspanned_seq<T>(
|
||||
@ -1002,16 +1006,19 @@ fn parse_unspanned_seq<T>(
|
||||
ket: &TokenKind,
|
||||
sep: SeqSep,
|
||||
f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>,
|
||||
) -> PResult<'a, (ThinVec<T>, bool)> {
|
||||
) -> PResult<'a, (ThinVec<T>, bool /* trailing */)> {
|
||||
self.expect(bra)?;
|
||||
self.parse_seq_to_end(ket, sep, f)
|
||||
}
|
||||
|
||||
/// Parses a comma-separated sequence, including both delimiters.
|
||||
/// The function `f` must consume tokens until reaching the next separator or
|
||||
/// closing bracket.
|
||||
fn parse_delim_comma_seq<T>(
|
||||
&mut self,
|
||||
delim: Delimiter,
|
||||
f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>,
|
||||
) -> PResult<'a, (ThinVec<T>, bool)> {
|
||||
) -> PResult<'a, (ThinVec<T>, bool /* trailing */)> {
|
||||
self.parse_unspanned_seq(
|
||||
&token::OpenDelim(delim),
|
||||
&token::CloseDelim(delim),
|
||||
@ -1020,10 +1027,13 @@ fn parse_delim_comma_seq<T>(
|
||||
)
|
||||
}
|
||||
|
||||
/// Parses a comma-separated sequence delimited by parentheses (e.g. `(x, y)`).
|
||||
/// The function `f` must consume tokens until reaching the next separator or
|
||||
/// closing bracket.
|
||||
fn parse_paren_comma_seq<T>(
|
||||
&mut self,
|
||||
f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>,
|
||||
) -> PResult<'a, (ThinVec<T>, bool)> {
|
||||
) -> PResult<'a, (ThinVec<T>, bool /* trailing */)> {
|
||||
self.parse_delim_comma_seq(Delimiter::Parenthesis, f)
|
||||
}
|
||||
|
||||
|
@ -1805,11 +1805,20 @@ function initSearch(rawSearchIndex) {
|
||||
return unifyFunctionTypes([row], [elem], whereClause, mgens);
|
||||
}
|
||||
|
||||
function checkPath(contains, ty, maxEditDistance) {
|
||||
/**
|
||||
* Compute an "edit distance" that ignores missing path elements.
|
||||
* @param {string[]} contains search query path
|
||||
* @param {Row} ty indexed item
|
||||
* @returns {null|number} edit distance
|
||||
*/
|
||||
function checkPath(contains, ty) {
|
||||
if (contains.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
let ret_dist = maxEditDistance + 1;
|
||||
const maxPathEditDistance = Math.floor(
|
||||
contains.reduce((acc, next) => acc + next.length, 0) / 3
|
||||
);
|
||||
let ret_dist = maxPathEditDistance + 1;
|
||||
const path = ty.path.split("::");
|
||||
|
||||
if (ty.parent && ty.parent.name) {
|
||||
@ -1821,15 +1830,23 @@ function initSearch(rawSearchIndex) {
|
||||
pathiter: for (let i = length - clength; i >= 0; i -= 1) {
|
||||
let dist_total = 0;
|
||||
for (let x = 0; x < clength; ++x) {
|
||||
const dist = editDistance(path[i + x], contains[x], maxEditDistance);
|
||||
if (dist > maxEditDistance) {
|
||||
continue pathiter;
|
||||
const [p, c] = [path[i + x], contains[x]];
|
||||
if (Math.floor((p.length - c.length) / 3) <= maxPathEditDistance &&
|
||||
p.indexOf(c) !== -1
|
||||
) {
|
||||
// discount distance on substring match
|
||||
dist_total += Math.floor((p.length - c.length) / 3);
|
||||
} else {
|
||||
const dist = editDistance(p, c, maxPathEditDistance);
|
||||
if (dist > maxPathEditDistance) {
|
||||
continue pathiter;
|
||||
}
|
||||
dist_total += dist;
|
||||
}
|
||||
dist_total += dist;
|
||||
}
|
||||
ret_dist = Math.min(ret_dist, Math.round(dist_total / clength));
|
||||
}
|
||||
return ret_dist;
|
||||
return ret_dist > maxPathEditDistance ? null : ret_dist;
|
||||
}
|
||||
|
||||
function typePassesFilter(filter, type) {
|
||||
@ -2030,8 +2047,8 @@ function initSearch(rawSearchIndex) {
|
||||
}
|
||||
|
||||
if (elem.fullPath.length > 1) {
|
||||
path_dist = checkPath(elem.pathWithoutLast, row, maxEditDistance);
|
||||
if (path_dist > maxEditDistance) {
|
||||
path_dist = checkPath(elem.pathWithoutLast, row);
|
||||
if (path_dist === null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -2045,7 +2062,7 @@ function initSearch(rawSearchIndex) {
|
||||
|
||||
const dist = editDistance(row.normalizedName, elem.normalizedPathLast, maxEditDistance);
|
||||
|
||||
if (index === -1 && dist + path_dist > maxEditDistance) {
|
||||
if (index === -1 && dist > maxEditDistance) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2100,13 +2117,9 @@ function initSearch(rawSearchIndex) {
|
||||
}
|
||||
|
||||
function innerRunQuery() {
|
||||
let queryLen = 0;
|
||||
for (const elem of parsedQuery.elems) {
|
||||
queryLen += elem.name.length;
|
||||
}
|
||||
for (const elem of parsedQuery.returned) {
|
||||
queryLen += elem.name.length;
|
||||
}
|
||||
const queryLen =
|
||||
parsedQuery.elems.reduce((acc, next) => acc + next.pathLast.length, 0) +
|
||||
parsedQuery.returned.reduce((acc, next) => acc + next.pathLast.length, 0);
|
||||
const maxEditDistance = Math.floor(queryLen / 3);
|
||||
|
||||
/**
|
||||
|
@ -7,7 +7,6 @@ const EXPECTED = {
|
||||
// Validate that type alias methods get the correct path.
|
||||
{ 'path': 'std::os::fd::AsRawFd', 'name': 'as_raw_fd' },
|
||||
{ 'path': 'std::os::fd::AsRawFd', 'name': 'as_raw_fd' },
|
||||
{ 'path': 'std::os::linux::process::PidFd', 'name': 'as_raw_fd' },
|
||||
{ 'path': 'std::os::fd::RawFd', 'name': 'as_raw_fd' },
|
||||
],
|
||||
};
|
||||
|
42
tests/rustdoc-js-std/path-maxeditdistance.js
Normal file
42
tests/rustdoc-js-std/path-maxeditdistance.js
Normal file
@ -0,0 +1,42 @@
|
||||
// exact-check
|
||||
const FILTER_CRATE = "std";
|
||||
const EXPECTED = [
|
||||
{
|
||||
query: 'vec::intoiterator',
|
||||
others: [
|
||||
// trait std::iter::IntoIterator is not the first result
|
||||
{ 'path': 'std::vec', 'name': 'IntoIter' },
|
||||
{ 'path': 'std::vec::Vec', 'name': 'into_iter' },
|
||||
{ 'path': 'std::vec::Drain', 'name': 'into_iter' },
|
||||
{ 'path': 'std::vec::IntoIter', 'name': 'into_iter' },
|
||||
{ 'path': 'std::vec::ExtractIf', 'name': 'into_iter' },
|
||||
{ 'path': 'std::vec::Splice', 'name': 'into_iter' },
|
||||
{ 'path': 'std::collections::VecDeque', 'name': 'into_iter' },
|
||||
],
|
||||
},
|
||||
{
|
||||
query: 'vec::iter',
|
||||
others: [
|
||||
// std::net::ToSocketAttrs::iter should not show up here
|
||||
{ 'path': 'std::vec', 'name': 'IntoIter' },
|
||||
{ 'path': 'std::vec::Vec', 'name': 'from_iter' },
|
||||
{ 'path': 'std::vec::Vec', 'name': 'into_iter' },
|
||||
{ 'path': 'std::vec::Drain', 'name': 'into_iter' },
|
||||
{ 'path': 'std::vec::IntoIter', 'name': 'into_iter' },
|
||||
{ 'path': 'std::vec::ExtractIf', 'name': 'into_iter' },
|
||||
{ 'path': 'std::vec::Splice', 'name': 'into_iter' },
|
||||
{ 'path': 'std::collections::VecDeque', 'name': 'iter' },
|
||||
{ 'path': 'std::collections::VecDeque', 'name': 'iter_mut' },
|
||||
{ 'path': 'std::collections::VecDeque', 'name': 'from_iter' },
|
||||
{ 'path': 'std::collections::VecDeque', 'name': 'into_iter' },
|
||||
],
|
||||
},
|
||||
{
|
||||
query: 'slice::itermut',
|
||||
others: [
|
||||
// std::collections::btree_map::itermut should not show up here
|
||||
{ 'path': 'std::slice', 'name': 'IterMut' },
|
||||
{ 'path': 'std::slice', 'name': 'iter_mut' },
|
||||
],
|
||||
},
|
||||
];
|
@ -1,11 +1,20 @@
|
||||
const EXPECTED = {
|
||||
query: 'hashset::insert',
|
||||
others: [
|
||||
// ensure hashset::insert comes first
|
||||
{ 'path': 'std::collections::hash_set::HashSet', 'name': 'insert' },
|
||||
{ 'path': 'std::collections::hash_set::HashSet', 'name': 'get_or_insert' },
|
||||
{ 'path': 'std::collections::hash_set::HashSet', 'name': 'get_or_insert_with' },
|
||||
{ 'path': 'std::collections::hash_set::HashSet', 'name': 'get_or_insert_owned' },
|
||||
{ 'path': 'std::collections::hash_map::HashMap', 'name': 'insert' },
|
||||
],
|
||||
};
|
||||
const EXPECTED = [
|
||||
{
|
||||
query: 'hashset::insert',
|
||||
others: [
|
||||
// ensure hashset::insert comes first
|
||||
{ 'path': 'std::collections::hash_set::HashSet', 'name': 'insert' },
|
||||
{ 'path': 'std::collections::hash_set::HashSet', 'name': 'get_or_insert' },
|
||||
{ 'path': 'std::collections::hash_set::HashSet', 'name': 'get_or_insert_with' },
|
||||
{ 'path': 'std::collections::hash_set::HashSet', 'name': 'get_or_insert_owned' },
|
||||
],
|
||||
},
|
||||
{
|
||||
query: 'hash::insert',
|
||||
others: [
|
||||
// ensure hashset/hashmap::insert come first
|
||||
{ 'path': 'std::collections::hash_map::HashMap', 'name': 'insert' },
|
||||
{ 'path': 'std::collections::hash_set::HashSet', 'name': 'insert' },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
@ -3,6 +3,5 @@ const EXPECTED = {
|
||||
'others': [
|
||||
{ 'path': 'exact_match::Si', 'name': 'pc' },
|
||||
{ 'path': 'exact_match::Psi', 'name': 'pc' },
|
||||
{ 'path': 'exact_match::Si', 'name': 'pa' },
|
||||
],
|
||||
};
|
||||
|
@ -1,7 +1,15 @@
|
||||
const EXPECTED = {
|
||||
'query': 'ig::pc',
|
||||
'others': [
|
||||
{ 'path': 'module_substring::Sig', 'name': 'pc' },
|
||||
{ 'path': 'module_substring::Si', 'name': 'pc' },
|
||||
],
|
||||
};
|
||||
const EXPECTED = [
|
||||
{
|
||||
'query': 'ig::pc',
|
||||
'others': [
|
||||
{ 'path': 'module_substring::Sig', 'name': 'pc' },
|
||||
],
|
||||
},
|
||||
{
|
||||
'query': 'si::pc',
|
||||
'others': [
|
||||
{ 'path': 'module_substring::Si', 'name': 'pc' },
|
||||
{ 'path': 'module_substring::Sig', 'name': 'pc' },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
35
tests/rustdoc-js/path-maxeditdistance.js
Normal file
35
tests/rustdoc-js/path-maxeditdistance.js
Normal file
@ -0,0 +1,35 @@
|
||||
// exact-check
|
||||
|
||||
const EXPECTED = [
|
||||
{
|
||||
'query': 'xxxxxxxxxxx::hocuspocusprestidigitation',
|
||||
// do not match abracadabra::hocuspocusprestidigitation
|
||||
'others': [],
|
||||
},
|
||||
{
|
||||
// exact match
|
||||
'query': 'abracadabra::hocuspocusprestidigitation',
|
||||
'others': [
|
||||
{ 'path': 'abracadabra', 'name': 'HocusPocusPrestidigitation' },
|
||||
],
|
||||
},
|
||||
{
|
||||
// swap br/rb; that's edit distance 2, where maxPathEditDistance = 3 (11 / 3)
|
||||
'query': 'arbacadarba::hocuspocusprestidigitation',
|
||||
'others': [
|
||||
{ 'path': 'abracadabra', 'name': 'HocusPocusPrestidigitation' },
|
||||
],
|
||||
},
|
||||
{
|
||||
// truncate 5 chars, where maxEditDistance = 7 (21 / 3)
|
||||
'query': 'abracadarba::hocusprestidigitation',
|
||||
'others': [
|
||||
{ 'path': 'abracadabra', 'name': 'HocusPocusPrestidigitation' },
|
||||
],
|
||||
},
|
||||
{
|
||||
// truncate 9 chars, where maxEditDistance = 5 (17 / 3)
|
||||
'query': 'abracadarba::hprestidigitation',
|
||||
'others': [],
|
||||
},
|
||||
];
|
3
tests/rustdoc-js/path-maxeditdistance.rs
Normal file
3
tests/rustdoc-js/path-maxeditdistance.rs
Normal file
@ -0,0 +1,3 @@
|
||||
#![crate_name="abracadabra"]
|
||||
|
||||
pub struct HocusPocusPrestidigitation;
|
@ -1,13 +1,13 @@
|
||||
// exact-check
|
||||
|
||||
const EXPECTED = {
|
||||
'query': 'b::ccccccc',
|
||||
'query': 'bbbbbb::ccccccc',
|
||||
'others': [
|
||||
// `ccccccc` is an exact match for all three of these.
|
||||
// However `b` is a closer match for `bb` than for any
|
||||
// of the others, so it ought to go first.
|
||||
{ 'path': 'path_ordering::bb', 'name': 'Ccccccc' },
|
||||
{ 'path': 'path_ordering::aa', 'name': 'Ccccccc' },
|
||||
{ 'path': 'path_ordering::dd', 'name': 'Ccccccc' },
|
||||
{ 'path': 'path_ordering::bbbbbb', 'name': 'Ccccccc' },
|
||||
{ 'path': 'path_ordering::abbbbb', 'name': 'Ccccccc' },
|
||||
{ 'path': 'path_ordering::dbbbbb', 'name': 'Ccccccc' },
|
||||
],
|
||||
};
|
||||
|
@ -1,9 +1,9 @@
|
||||
pub mod dd {
|
||||
pub mod dbbbbb {
|
||||
pub struct Ccccccc;
|
||||
}
|
||||
pub mod aa {
|
||||
pub mod abbbbb {
|
||||
pub struct Ccccccc;
|
||||
}
|
||||
pub mod bb {
|
||||
pub mod bbbbbb {
|
||||
pub struct Ccccccc;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ fn main() {
|
||||
}
|
||||
match x as i32 {
|
||||
0..5+1 => errors_only.push(x),
|
||||
//~^ error: expected one of `,`, `=>`, `if`, `|`, or `}`, found `+`
|
||||
//~^ error: expected one of `=>`, `if`, or `|`, found `+`
|
||||
1 | -3..0 => first_or.push(x),
|
||||
y @ (0..5 | 6) => or_two.push(y),
|
||||
y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
|
||||
|
@ -1,8 +1,8 @@
|
||||
error: expected one of `,`, `=>`, `if`, `|`, or `}`, found `+`
|
||||
error: expected one of `=>`, `if`, or `|`, found `+`
|
||||
--> $DIR/range_pat_interactions1.rs:19:17
|
||||
|
|
||||
LL | 0..5+1 => errors_only.push(x),
|
||||
| ^ expected one of `,`, `=>`, `if`, `|`, or `}`
|
||||
| ^ expected one of `=>`, `if`, or `|`
|
||||
|
||||
error[E0408]: variable `n` is not bound in all patterns
|
||||
--> $DIR/range_pat_interactions1.rs:10:25
|
||||
|
@ -9,7 +9,7 @@ fn main() {
|
||||
match x as i32 {
|
||||
0..=(5+1) => errors_only.push(x),
|
||||
//~^ error: inclusive range with no end
|
||||
//~| error: expected one of `,`, `=>`, `if`, `|`, or `}`, found `(`
|
||||
//~| error: expected one of `=>`, `if`, or `|`, found `(`
|
||||
1 | -3..0 => first_or.push(x),
|
||||
y @ (0..5 | 6) => or_two.push(y),
|
||||
y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
|
||||
|
@ -6,11 +6,11 @@ LL | 0..=(5+1) => errors_only.push(x),
|
||||
|
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error: expected one of `,`, `=>`, `if`, `|`, or `}`, found `(`
|
||||
error: expected one of `=>`, `if`, or `|`, found `(`
|
||||
--> $DIR/range_pat_interactions2.rs:10:17
|
||||
|
|
||||
LL | 0..=(5+1) => errors_only.push(x),
|
||||
| ^ expected one of `,`, `=>`, `if`, `|`, or `}`
|
||||
| ^ expected one of `=>`, `if`, or `|`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
33
tests/ui/impl-trait/not_general_enough_regression_106630.rs
Normal file
33
tests/ui/impl-trait/not_general_enough_regression_106630.rs
Normal file
@ -0,0 +1,33 @@
|
||||
// edition:2018
|
||||
// run-pass
|
||||
|
||||
use std::future::Future;
|
||||
|
||||
trait AsyncCallback<'a> {
|
||||
type Out;
|
||||
}
|
||||
|
||||
impl<'a, Fut, T, F> AsyncCallback<'a> for F
|
||||
where
|
||||
F: FnOnce(&'a mut ()) -> Fut,
|
||||
Fut: Future<Output = T> + Send + 'a,
|
||||
{
|
||||
type Out = T;
|
||||
}
|
||||
|
||||
trait CallbackMarker {}
|
||||
|
||||
impl<F, T> CallbackMarker for F
|
||||
where
|
||||
T: 'static,
|
||||
for<'a> F: AsyncCallback<'a, Out = T> + Send,
|
||||
{
|
||||
}
|
||||
|
||||
fn do_sth<F: CallbackMarker>(_: F) {}
|
||||
|
||||
async fn callback(_: &mut ()) -> impl Send {}
|
||||
|
||||
fn main() {
|
||||
do_sth(callback);
|
||||
}
|
@ -84,15 +84,15 @@ fn main() {}
|
||||
|
||||
#[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } }
|
||||
//~^ ERROR inclusive range with no end
|
||||
//~| ERROR expected one of `,`, `=>`, `if`, `|`, or `}`, found `#`
|
||||
//~| ERROR expected one of `=>`, `if`, or `|`, found `#`
|
||||
#[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } }
|
||||
//~^ ERROR inclusive range with no end
|
||||
//~| ERROR expected one of `,`, `=>`, `if`, `|`, or `}`, found `#`
|
||||
//~| ERROR expected one of `=>`, `if`, or `|`, found `#`
|
||||
#[cfg(FALSE)] fn e() { match 0 { 0..=-#[attr] 10 => () } }
|
||||
//~^ ERROR unexpected token: `#`
|
||||
#[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } }
|
||||
//~^ ERROR inclusive range with no end
|
||||
//~| ERROR expected one of `,`, `=>`, `if`, `|`, or `}`, found `#`
|
||||
//~| ERROR expected one of `=>`, `if`, or `|`, found `#`
|
||||
|
||||
#[cfg(FALSE)] fn e() { let _ = x.#![attr]foo(); }
|
||||
//~^ ERROR unexpected token: `#`
|
||||
|
@ -365,11 +365,11 @@ LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } }
|
||||
|
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error: expected one of `,`, `=>`, `if`, `|`, or `}`, found `#`
|
||||
error: expected one of `=>`, `if`, or `|`, found `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:85:38
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } }
|
||||
| ^ expected one of `,`, `=>`, `if`, `|`, or `}`
|
||||
| ^ expected one of `=>`, `if`, or `|`
|
||||
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:88:35
|
||||
@ -379,11 +379,11 @@ LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } }
|
||||
|
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error: expected one of `,`, `=>`, `if`, `|`, or `}`, found `#`
|
||||
error: expected one of `=>`, `if`, or `|`, found `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:88:38
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } }
|
||||
| ^ expected one of `,`, `=>`, `if`, `|`, or `}`
|
||||
| ^ expected one of `=>`, `if`, or `|`
|
||||
|
||||
error: unexpected token: `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:91:39
|
||||
@ -399,11 +399,11 @@ LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } }
|
||||
|
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error: expected one of `,`, `=>`, `if`, `|`, or `}`, found `#`
|
||||
error: expected one of `=>`, `if`, or `|`, found `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:93:38
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } }
|
||||
| ^ expected one of `,`, `=>`, `if`, `|`, or `}`
|
||||
| ^ expected one of `=>`, `if`, or `|`
|
||||
|
||||
error: unexpected token: `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:97:34
|
||||
|
@ -3,7 +3,7 @@
|
||||
fn main() {
|
||||
let z = "hello";
|
||||
match z {
|
||||
tmp[0] => {} //~ ERROR expected one of `,`, `=>`, `@`, `if`, `|`, or `}`, found `[`
|
||||
tmp[0] => {} //~ ERROR expected one of `=>`, `@`, `if`, or `|`, found `[`
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
error: expected one of `,`, `=>`, `@`, `if`, `|`, or `}`, found `[`
|
||||
error: expected one of `=>`, `@`, `if`, or `|`, found `[`
|
||||
--> $DIR/issue-24375.rs:6:12
|
||||
|
|
||||
LL | tmp[0] => {}
|
||||
| ^ expected one of `,`, `=>`, `@`, `if`, `|`, or `}`
|
||||
| ^ expected one of `=>`, `@`, `if`, or `|`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
error: expected one of `,`, `=>`, `if`, `|`, or `}`, found reserved identifier `_`
|
||||
error: expected one of `=>`, `if`, or `|`, found reserved identifier `_`
|
||||
--> $DIR/match-arm-without-body.rs:13:9
|
||||
|
|
||||
LL | Some(_)
|
||||
| - expected one of `,`, `=>`, `if`, `|`, or `}`
|
||||
| - expected one of `=>`, `if`, or `|`
|
||||
LL | _ => {}
|
||||
| ^ unexpected token
|
||||
|
||||
@ -44,11 +44,11 @@ LL +
|
||||
LL ~ _ => {}
|
||||
|
|
||||
|
||||
error: expected one of `,`, `.`, `=>`, `?`, `}`, or an operator, found reserved identifier `_`
|
||||
error: expected one of `.`, `=>`, `?`, or an operator, found reserved identifier `_`
|
||||
--> $DIR/match-arm-without-body.rs:36:9
|
||||
|
|
||||
LL | Some(_) if true
|
||||
| - expected one of `,`, `.`, `=>`, `?`, `}`, or an operator
|
||||
| - expected one of `.`, `=>`, `?`, or an operator
|
||||
LL | _ => {}
|
||||
| ^ unexpected token
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
fn main() {
|
||||
match 42 {
|
||||
x < 7 => (),
|
||||
//~^ error: expected one of `,`, `=>`, `@`, `if`, `|`, or `}`, found `<`
|
||||
//~^ error: expected one of `=>`, `@`, `if`, or `|`, found `<`
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
error: expected one of `,`, `=>`, `@`, `if`, `|`, or `}`, found `<`
|
||||
error: expected one of `=>`, `@`, `if`, or `|`, found `<`
|
||||
--> $DIR/pat-lt-bracket-1.rs:3:7
|
||||
|
|
||||
LL | x < 7 => (),
|
||||
| ^ expected one of `,`, `=>`, `@`, `if`, `|`, or `}`
|
||||
| ^ expected one of `=>`, `@`, `if`, or `|`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user