syntax: Better recovery for $ty::AssocItem
and ty!()::AssocItem
This commit is contained in:
parent
7486b9c208
commit
18229bb1ad
7 changed files with 198 additions and 77 deletions
|
@ -154,6 +154,21 @@ macro_rules! maybe_whole {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If the next tokens are ill-formed `$ty::` recover them as `<$ty>::`.
|
||||||
|
macro_rules! maybe_recover_from_interpolated_ty_qpath {
|
||||||
|
($self: expr, $allow_qpath_recovery: expr) => {
|
||||||
|
if $allow_qpath_recovery && $self.look_ahead(1, |t| t == &token::ModSep) {
|
||||||
|
if let token::Interpolated(nt) = &$self.token {
|
||||||
|
if let token::NtTy(ty) = &**nt {
|
||||||
|
let ty = ty.clone();
|
||||||
|
$self.bump();
|
||||||
|
return $self.maybe_recover_from_bad_qpath_stage_2($self.prev_span, ty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn maybe_append(mut lhs: Vec<Attribute>, mut rhs: Option<Vec<Attribute>>) -> Vec<Attribute> {
|
fn maybe_append(mut lhs: Vec<Attribute>, mut rhs: Option<Vec<Attribute>>) -> Vec<Attribute> {
|
||||||
if let Some(ref mut rhs) = rhs {
|
if let Some(ref mut rhs) = rhs {
|
||||||
lhs.append(rhs);
|
lhs.append(rhs);
|
||||||
|
@ -172,11 +187,10 @@ enum PrevTokenKind {
|
||||||
Other,
|
Other,
|
||||||
}
|
}
|
||||||
|
|
||||||
trait RecoverQPath: Sized {
|
trait RecoverQPath: Sized + 'static {
|
||||||
const PATH_STYLE: PathStyle = PathStyle::Expr;
|
const PATH_STYLE: PathStyle = PathStyle::Expr;
|
||||||
fn to_ty(&self) -> Option<P<Ty>>;
|
fn to_ty(&self) -> Option<P<Ty>>;
|
||||||
fn to_recovered(&self, qself: Option<QSelf>, path: ast::Path) -> Self;
|
fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self;
|
||||||
fn to_string(&self) -> String;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RecoverQPath for Ty {
|
impl RecoverQPath for Ty {
|
||||||
|
@ -184,11 +198,8 @@ impl RecoverQPath for Ty {
|
||||||
fn to_ty(&self) -> Option<P<Ty>> {
|
fn to_ty(&self) -> Option<P<Ty>> {
|
||||||
Some(P(self.clone()))
|
Some(P(self.clone()))
|
||||||
}
|
}
|
||||||
fn to_recovered(&self, qself: Option<QSelf>, path: ast::Path) -> Self {
|
fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self {
|
||||||
Self { span: path.span, node: TyKind::Path(qself, path), id: self.id }
|
Self { span: path.span, node: TyKind::Path(qself, path), id: ast::DUMMY_NODE_ID }
|
||||||
}
|
|
||||||
fn to_string(&self) -> String {
|
|
||||||
pprust::ty_to_string(self)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,11 +207,8 @@ impl RecoverQPath for Pat {
|
||||||
fn to_ty(&self) -> Option<P<Ty>> {
|
fn to_ty(&self) -> Option<P<Ty>> {
|
||||||
self.to_ty()
|
self.to_ty()
|
||||||
}
|
}
|
||||||
fn to_recovered(&self, qself: Option<QSelf>, path: ast::Path) -> Self {
|
fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self {
|
||||||
Self { span: path.span, node: PatKind::Path(qself, path), id: self.id }
|
Self { span: path.span, node: PatKind::Path(qself, path), id: ast::DUMMY_NODE_ID }
|
||||||
}
|
|
||||||
fn to_string(&self) -> String {
|
|
||||||
pprust::pat_to_string(self)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,12 +216,9 @@ impl RecoverQPath for Expr {
|
||||||
fn to_ty(&self) -> Option<P<Ty>> {
|
fn to_ty(&self) -> Option<P<Ty>> {
|
||||||
self.to_ty()
|
self.to_ty()
|
||||||
}
|
}
|
||||||
fn to_recovered(&self, qself: Option<QSelf>, path: ast::Path) -> Self {
|
fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self {
|
||||||
Self { span: path.span, node: ExprKind::Path(qself, path),
|
Self { span: path.span, node: ExprKind::Path(qself, path),
|
||||||
id: self.id, attrs: self.attrs.clone() }
|
attrs: ThinVec::new(), id: ast::DUMMY_NODE_ID }
|
||||||
}
|
|
||||||
fn to_string(&self) -> String {
|
|
||||||
pprust::expr_to_string(self)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1651,6 +1656,7 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
fn parse_ty_common(&mut self, allow_plus: bool, allow_qpath_recovery: bool,
|
fn parse_ty_common(&mut self, allow_plus: bool, allow_qpath_recovery: bool,
|
||||||
allow_c_variadic: bool) -> PResult<'a, P<Ty>> {
|
allow_c_variadic: bool) -> PResult<'a, P<Ty>> {
|
||||||
|
maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery);
|
||||||
maybe_whole!(self, NtTy, |x| x);
|
maybe_whole!(self, NtTy, |x| x);
|
||||||
|
|
||||||
let lo = self.span;
|
let lo = self.span;
|
||||||
|
@ -1802,14 +1808,12 @@ impl<'a> Parser<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let span = lo.to(self.prev_span);
|
let span = lo.to(self.prev_span);
|
||||||
let ty = Ty { node, span, id: ast::DUMMY_NODE_ID };
|
let ty = P(Ty { node, span, id: ast::DUMMY_NODE_ID });
|
||||||
|
|
||||||
// Try to recover from use of `+` with incorrect priority.
|
// Try to recover from use of `+` with incorrect priority.
|
||||||
self.maybe_report_ambiguous_plus(allow_plus, impl_dyn_multi, &ty);
|
self.maybe_report_ambiguous_plus(allow_plus, impl_dyn_multi, &ty);
|
||||||
self.maybe_recover_from_bad_type_plus(allow_plus, &ty)?;
|
self.maybe_recover_from_bad_type_plus(allow_plus, &ty)?;
|
||||||
let ty = self.maybe_recover_from_bad_qpath(ty, allow_qpath_recovery)?;
|
self.maybe_recover_from_bad_qpath(ty, allow_qpath_recovery)
|
||||||
|
|
||||||
Ok(P(ty))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_remaining_bounds(&mut self, generic_params: Vec<GenericParam>, path: ast::Path,
|
fn parse_remaining_bounds(&mut self, generic_params: Vec<GenericParam>, path: ast::Path,
|
||||||
|
@ -1881,35 +1885,35 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to recover from associated item paths like `[T]::AssocItem`/`(T, U)::AssocItem`.
|
// Try to recover from associated item paths like `[T]::AssocItem`/`(T, U)::AssocItem`.
|
||||||
fn maybe_recover_from_bad_qpath<T: RecoverQPath>(&mut self, base: T, allow_recovery: bool)
|
fn maybe_recover_from_bad_qpath<T: RecoverQPath>(&mut self, base: P<T>, allow_recovery: bool)
|
||||||
-> PResult<'a, T> {
|
-> PResult<'a, P<T>> {
|
||||||
// Do not add `::` to expected tokens.
|
// Do not add `::` to expected tokens.
|
||||||
if !allow_recovery || self.token != token::ModSep {
|
if allow_recovery && self.token == token::ModSep {
|
||||||
return Ok(base);
|
if let Some(ty) = base.to_ty() {
|
||||||
|
return self.maybe_recover_from_bad_qpath_stage_2(ty.span, ty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(base)
|
||||||
}
|
}
|
||||||
let ty = match base.to_ty() {
|
|
||||||
Some(ty) => ty,
|
|
||||||
None => return Ok(base),
|
|
||||||
};
|
|
||||||
|
|
||||||
self.bump(); // `::`
|
fn maybe_recover_from_bad_qpath_stage_2<T: RecoverQPath>(&mut self, ty_span: Span, ty: P<Ty>)
|
||||||
let mut segments = Vec::new();
|
-> PResult<'a, P<T>> {
|
||||||
self.parse_path_segments(&mut segments, T::PATH_STYLE, true)?;
|
self.expect(&token::ModSep)?;
|
||||||
|
|
||||||
let span = ty.span.to(self.prev_span);
|
let mut path = ast::Path { segments: Vec::new(), span: syntax_pos::DUMMY_SP };
|
||||||
let path_span = span.to(span); // use an empty path since `position` == 0
|
self.parse_path_segments(&mut path.segments, T::PATH_STYLE, true)?;
|
||||||
let recovered = base.to_recovered(
|
path.span = ty_span.to(self.prev_span);
|
||||||
Some(QSelf { ty, path_span, position: 0 }),
|
|
||||||
ast::Path { segments, span },
|
|
||||||
);
|
|
||||||
|
|
||||||
|
let ty_str = self.sess.source_map().span_to_snippet(ty_span)
|
||||||
|
.unwrap_or_else(|_| pprust::ty_to_string(&ty));
|
||||||
self.diagnostic()
|
self.diagnostic()
|
||||||
.struct_span_err(span, "missing angle brackets in associated item path")
|
.struct_span_err(path.span, "missing angle brackets in associated item path")
|
||||||
.span_suggestion( // this is a best-effort recovery
|
.span_suggestion( // this is a best-effort recovery
|
||||||
span, "try", recovered.to_string(), Applicability::MaybeIncorrect
|
path.span, "try", format!("<{}>::{}", ty_str, path), Applicability::MaybeIncorrect
|
||||||
).emit();
|
).emit();
|
||||||
|
|
||||||
Ok(recovered)
|
let path_span = path.span.to(path.span); // use an empty path since `position` == 0
|
||||||
|
Ok(P(T::recovered(Some(QSelf { ty, path_span, position: 0 }), path)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> {
|
fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> {
|
||||||
|
@ -2574,15 +2578,6 @@ impl<'a> Parser<'a> {
|
||||||
ExprKind::AssignOp(binop, lhs, rhs)
|
ExprKind::AssignOp(binop, lhs, rhs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mk_mac_expr(&mut self, span: Span, m: Mac_, attrs: ThinVec<Attribute>) -> P<Expr> {
|
|
||||||
P(Expr {
|
|
||||||
id: ast::DUMMY_NODE_ID,
|
|
||||||
node: ExprKind::Mac(source_map::Spanned {node: m, span: span}),
|
|
||||||
span,
|
|
||||||
attrs,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn expect_delimited_token_tree(&mut self) -> PResult<'a, (MacDelimiter, TokenStream)> {
|
fn expect_delimited_token_tree(&mut self) -> PResult<'a, (MacDelimiter, TokenStream)> {
|
||||||
let delim = match self.token {
|
let delim = match self.token {
|
||||||
token::OpenDelim(delim) => delim,
|
token::OpenDelim(delim) => delim,
|
||||||
|
@ -2612,6 +2607,7 @@ impl<'a> Parser<'a> {
|
||||||
/// N.B., this does not parse outer attributes, and is private because it only works
|
/// N.B., this does not parse outer attributes, and is private because it only works
|
||||||
/// correctly if called from `parse_dot_or_call_expr()`.
|
/// correctly if called from `parse_dot_or_call_expr()`.
|
||||||
fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> {
|
fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> {
|
||||||
|
maybe_recover_from_interpolated_ty_qpath!(self, true);
|
||||||
maybe_whole_expr!(self);
|
maybe_whole_expr!(self);
|
||||||
|
|
||||||
// Outer attributes are already parsed and will be
|
// Outer attributes are already parsed and will be
|
||||||
|
@ -2826,29 +2822,23 @@ impl<'a> Parser<'a> {
|
||||||
db.note("variable declaration using `let` is a statement");
|
db.note("variable declaration using `let` is a statement");
|
||||||
return Err(db);
|
return Err(db);
|
||||||
} else if self.token.is_path_start() {
|
} else if self.token.is_path_start() {
|
||||||
let pth = self.parse_path(PathStyle::Expr)?;
|
let path = self.parse_path(PathStyle::Expr)?;
|
||||||
|
|
||||||
// `!`, as an operator, is prefix, so we know this isn't that
|
// `!`, as an operator, is prefix, so we know this isn't that
|
||||||
if self.eat(&token::Not) {
|
if self.eat(&token::Not) {
|
||||||
// MACRO INVOCATION expression
|
// MACRO INVOCATION expression
|
||||||
let (delim, tts) = self.expect_delimited_token_tree()?;
|
let (delim, tts) = self.expect_delimited_token_tree()?;
|
||||||
let hi = self.prev_span;
|
hi = self.prev_span;
|
||||||
let node = Mac_ { path: pth, tts, delim };
|
ex = ExprKind::Mac(respan(lo.to(hi), Mac_ { path, tts, delim }));
|
||||||
return Ok(self.mk_mac_expr(lo.to(hi), node, attrs))
|
} else if self.check(&token::OpenDelim(token::Brace)) &&
|
||||||
}
|
!self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL) {
|
||||||
if self.check(&token::OpenDelim(token::Brace)) {
|
|
||||||
// This is a struct literal, unless we're prohibited
|
// This is a struct literal, unless we're prohibited
|
||||||
// from parsing struct literals here.
|
// from parsing struct literals here.
|
||||||
let prohibited = self.restrictions.contains(
|
return self.parse_struct_expr(lo, path, attrs);
|
||||||
Restrictions::NO_STRUCT_LITERAL
|
} else {
|
||||||
);
|
hi = path.span;
|
||||||
if !prohibited {
|
ex = ExprKind::Path(None, path);
|
||||||
return self.parse_struct_expr(lo, pth, attrs);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
hi = pth.span;
|
|
||||||
ex = ExprKind::Path(None, pth);
|
|
||||||
} else {
|
} else {
|
||||||
if !self.unclosed_delims.is_empty() && self.check(&token::Semi) {
|
if !self.unclosed_delims.is_empty() && self.check(&token::Semi) {
|
||||||
// Don't complain about bare semicolons after unclosed braces
|
// Don't complain about bare semicolons after unclosed braces
|
||||||
|
@ -2883,10 +2873,8 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let expr = Expr { node: ex, span: lo.to(hi), id: ast::DUMMY_NODE_ID, attrs };
|
let expr = self.mk_expr(lo.to(hi), ex, attrs);
|
||||||
let expr = self.maybe_recover_from_bad_qpath(expr, true)?;
|
self.maybe_recover_from_bad_qpath(expr, true)
|
||||||
|
|
||||||
return Ok(P(expr));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_struct_expr(&mut self, lo: Span, pth: ast::Path, mut attrs: ThinVec<Attribute>)
|
fn parse_struct_expr(&mut self, lo: Span, pth: ast::Path, mut attrs: ThinVec<Attribute>)
|
||||||
|
@ -4581,6 +4569,7 @@ impl<'a> Parser<'a> {
|
||||||
allow_range_pat: bool,
|
allow_range_pat: bool,
|
||||||
expected: Option<&'static str>,
|
expected: Option<&'static str>,
|
||||||
) -> PResult<'a, P<Pat>> {
|
) -> PResult<'a, P<Pat>> {
|
||||||
|
maybe_recover_from_interpolated_ty_qpath!(self, true);
|
||||||
maybe_whole!(self, NtPat, |x| x);
|
maybe_whole!(self, NtPat, |x| x);
|
||||||
|
|
||||||
let lo = self.span;
|
let lo = self.span;
|
||||||
|
@ -4756,7 +4745,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let pat = Pat { node: pat, span: lo.to(self.prev_span), id: ast::DUMMY_NODE_ID };
|
let pat = P(Pat { node: pat, span: lo.to(self.prev_span), id: ast::DUMMY_NODE_ID });
|
||||||
let pat = self.maybe_recover_from_bad_qpath(pat, true)?;
|
let pat = self.maybe_recover_from_bad_qpath(pat, true)?;
|
||||||
|
|
||||||
if !allow_range_pat {
|
if !allow_range_pat {
|
||||||
|
@ -4782,7 +4771,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(P(pat))
|
Ok(pat)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses `ident` or `ident @ pat`.
|
/// Parses `ident` or `ident @ pat`.
|
||||||
|
@ -5250,7 +5239,8 @@ impl<'a> Parser<'a> {
|
||||||
self.warn_missing_semicolon();
|
self.warn_missing_semicolon();
|
||||||
StmtKind::Mac(P((mac, style, attrs.into())))
|
StmtKind::Mac(P((mac, style, attrs.into())))
|
||||||
} else {
|
} else {
|
||||||
let e = self.mk_mac_expr(lo.to(hi), mac.node, ThinVec::new());
|
let e = self.mk_expr(mac.span, ExprKind::Mac(mac), ThinVec::new());
|
||||||
|
let e = self.maybe_recover_from_bad_qpath(e, true)?;
|
||||||
let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?;
|
let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?;
|
||||||
let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?;
|
let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?;
|
||||||
StmtKind::Expr(e)
|
StmtKind::Expr(e)
|
||||||
|
|
|
@ -18,3 +18,19 @@ fn main() {
|
||||||
10 + (u8)::clone(&0);
|
10 + (u8)::clone(&0);
|
||||||
//~^ ERROR missing angle brackets in associated item path
|
//~^ ERROR missing angle brackets in associated item path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! expr {
|
||||||
|
($ty: ty) => ($ty::clone(&0))
|
||||||
|
//~^ ERROR missing angle brackets in associated item path
|
||||||
|
}
|
||||||
|
macro_rules! ty {
|
||||||
|
() => (u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_macros() {
|
||||||
|
expr!(u8);
|
||||||
|
let _ = ty!()::clone(&0);
|
||||||
|
//~^ ERROR missing angle brackets in associated item path
|
||||||
|
ty!()::clone(&0);
|
||||||
|
//~^ ERROR missing angle brackets in associated item path
|
||||||
|
}
|
||||||
|
|
|
@ -34,5 +34,26 @@ error: missing angle brackets in associated item path
|
||||||
LL | 10 + (u8)::clone(&0);
|
LL | 10 + (u8)::clone(&0);
|
||||||
| ^^^^^^^^^^^ help: try: `<(u8)>::clone`
|
| ^^^^^^^^^^^ help: try: `<(u8)>::clone`
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
error: missing angle brackets in associated item path
|
||||||
|
--> $DIR/bad-assoc-expr.rs:32:13
|
||||||
|
|
|
||||||
|
LL | let _ = ty!()::clone(&0);
|
||||||
|
| ^^^^^^^^^^^^ help: try: `<ty!()>::clone`
|
||||||
|
|
||||||
|
error: missing angle brackets in associated item path
|
||||||
|
--> $DIR/bad-assoc-expr.rs:34:5
|
||||||
|
|
|
||||||
|
LL | ty!()::clone(&0);
|
||||||
|
| ^^^^^^^^^^^^ help: try: `<ty!()>::clone`
|
||||||
|
|
||||||
|
error: missing angle brackets in associated item path
|
||||||
|
--> $DIR/bad-assoc-expr.rs:23:19
|
||||||
|
|
|
||||||
|
LL | ($ty: ty) => ($ty::clone(&0))
|
||||||
|
| ^^^^^^^^^^ help: try: `<$ty>::clone`
|
||||||
|
...
|
||||||
|
LL | expr!(u8);
|
||||||
|
| ---------- in this macro invocation
|
||||||
|
|
||||||
|
error: aborting due to 9 previous errors
|
||||||
|
|
||||||
|
|
|
@ -16,3 +16,21 @@ fn main() {
|
||||||
//~| ERROR no associated item named `AssocItem` found for type `(u8,)` in the current scope
|
//~| ERROR no associated item named `AssocItem` found for type `(u8,)` in the current scope
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! pat {
|
||||||
|
($ty: ty) => ($ty::AssocItem)
|
||||||
|
//~^ ERROR missing angle brackets in associated item path
|
||||||
|
//~| ERROR no associated item named `AssocItem` found for type `u8` in the current scope
|
||||||
|
}
|
||||||
|
macro_rules! ty {
|
||||||
|
() => (u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_macros() {
|
||||||
|
match 0u8 {
|
||||||
|
pat!(u8) => {}
|
||||||
|
ty!()::AssocItem => {}
|
||||||
|
//~^ ERROR missing angle brackets in associated item path
|
||||||
|
//~| ERROR no associated item named `AssocItem` found for type `u8` in the current scope
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -22,6 +22,21 @@ error: missing angle brackets in associated item path
|
||||||
LL | &(u8,)::AssocItem => {}
|
LL | &(u8,)::AssocItem => {}
|
||||||
| ^^^^^^^^^^^^^^^^ help: try: `<(u8,)>::AssocItem`
|
| ^^^^^^^^^^^^^^^^ help: try: `<(u8,)>::AssocItem`
|
||||||
|
|
||||||
|
error: missing angle brackets in associated item path
|
||||||
|
--> $DIR/bad-assoc-pat.rs:32:9
|
||||||
|
|
|
||||||
|
LL | ty!()::AssocItem => {}
|
||||||
|
| ^^^^^^^^^^^^^^^^ help: try: `<ty!()>::AssocItem`
|
||||||
|
|
||||||
|
error: missing angle brackets in associated item path
|
||||||
|
--> $DIR/bad-assoc-pat.rs:21:19
|
||||||
|
|
|
||||||
|
LL | ($ty: ty) => ($ty::AssocItem)
|
||||||
|
| ^^^^^^^^^^^^^^ help: try: `<$ty>::AssocItem`
|
||||||
|
...
|
||||||
|
LL | pat!(u8) => {}
|
||||||
|
| -------- in this macro invocation
|
||||||
|
|
||||||
error[E0599]: no associated item named `AssocItem` found for type `[u8]` in the current scope
|
error[E0599]: no associated item named `AssocItem` found for type `[u8]` in the current scope
|
||||||
--> $DIR/bad-assoc-pat.rs:3:15
|
--> $DIR/bad-assoc-pat.rs:3:15
|
||||||
|
|
|
|
||||||
|
@ -54,6 +69,25 @@ LL | &(u8,)::AssocItem => {}
|
||||||
| |
|
| |
|
||||||
| associated item not found in `(u8,)`
|
| associated item not found in `(u8,)`
|
||||||
|
|
||||||
error: aborting due to 8 previous errors
|
error[E0599]: no associated item named `AssocItem` found for type `u8` in the current scope
|
||||||
|
--> $DIR/bad-assoc-pat.rs:21:24
|
||||||
|
|
|
||||||
|
LL | ($ty: ty) => ($ty::AssocItem)
|
||||||
|
| -----^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| associated item not found in `u8`
|
||||||
|
...
|
||||||
|
LL | pat!(u8) => {}
|
||||||
|
| -------- in this macro invocation
|
||||||
|
|
||||||
|
error[E0599]: no associated item named `AssocItem` found for type `u8` in the current scope
|
||||||
|
--> $DIR/bad-assoc-pat.rs:32:16
|
||||||
|
|
|
||||||
|
LL | ty!()::AssocItem => {}
|
||||||
|
| -------^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| associated item not found in `u8`
|
||||||
|
|
||||||
|
error: aborting due to 12 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0599`.
|
For more information about this error, try `rustc --explain E0599`.
|
||||||
|
|
|
@ -33,4 +33,16 @@ type G = 'static + (Send)::AssocTy;
|
||||||
type H = Fn(u8) -> (u8)::Output;
|
type H = Fn(u8) -> (u8)::Output;
|
||||||
//~^ ERROR ambiguous associated type
|
//~^ ERROR ambiguous associated type
|
||||||
|
|
||||||
|
macro_rules! ty {
|
||||||
|
($ty: ty) => ($ty::AssocTy);
|
||||||
|
//~^ ERROR missing angle brackets in associated item path
|
||||||
|
//~| ERROR ambiguous associated type
|
||||||
|
() => (u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
type J = ty!(u8);
|
||||||
|
type I = ty!()::AssocTy;
|
||||||
|
//~^ ERROR missing angle brackets in associated item path
|
||||||
|
//~| ERROR ambiguous associated type
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -38,7 +38,22 @@ error: missing angle brackets in associated item path
|
||||||
--> $DIR/bad-assoc-ty.rs:27:10
|
--> $DIR/bad-assoc-ty.rs:27:10
|
||||||
|
|
|
|
||||||
LL | type G = 'static + (Send)::AssocTy;
|
LL | type G = 'static + (Send)::AssocTy;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `<'static + Send>::AssocTy`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `<'static + (Send)>::AssocTy`
|
||||||
|
|
||||||
|
error: missing angle brackets in associated item path
|
||||||
|
--> $DIR/bad-assoc-ty.rs:44:10
|
||||||
|
|
|
||||||
|
LL | type I = ty!()::AssocTy;
|
||||||
|
| ^^^^^^^^^^^^^^ help: try: `<ty!()>::AssocTy`
|
||||||
|
|
||||||
|
error: missing angle brackets in associated item path
|
||||||
|
--> $DIR/bad-assoc-ty.rs:37:19
|
||||||
|
|
|
||||||
|
LL | ($ty: ty) => ($ty::AssocTy);
|
||||||
|
| ^^^^^^^^^^^^ help: try: `<$ty>::AssocTy`
|
||||||
|
...
|
||||||
|
LL | type J = ty!(u8);
|
||||||
|
| ------- in this macro invocation
|
||||||
|
|
||||||
error[E0223]: ambiguous associated type
|
error[E0223]: ambiguous associated type
|
||||||
--> $DIR/bad-assoc-ty.rs:1:10
|
--> $DIR/bad-assoc-ty.rs:1:10
|
||||||
|
@ -88,7 +103,22 @@ error[E0223]: ambiguous associated type
|
||||||
LL | type H = Fn(u8) -> (u8)::Output;
|
LL | type H = Fn(u8) -> (u8)::Output;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<(dyn std::ops::Fn(u8) -> u8 + 'static) as Trait>::Output`
|
| ^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<(dyn std::ops::Fn(u8) -> u8 + 'static) as Trait>::Output`
|
||||||
|
|
||||||
error: aborting due to 15 previous errors
|
error[E0223]: ambiguous associated type
|
||||||
|
--> $DIR/bad-assoc-ty.rs:37:19
|
||||||
|
|
|
||||||
|
LL | ($ty: ty) => ($ty::AssocTy);
|
||||||
|
| ^^^^^^^^^^^^ help: use fully-qualified syntax: `<u8 as Trait>::AssocTy`
|
||||||
|
...
|
||||||
|
LL | type J = ty!(u8);
|
||||||
|
| ------- in this macro invocation
|
||||||
|
|
||||||
|
error[E0223]: ambiguous associated type
|
||||||
|
--> $DIR/bad-assoc-ty.rs:44:10
|
||||||
|
|
|
||||||
|
LL | type I = ty!()::AssocTy;
|
||||||
|
| ^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<u8 as Trait>::AssocTy`
|
||||||
|
|
||||||
|
error: aborting due to 19 previous errors
|
||||||
|
|
||||||
Some errors occurred: E0121, E0223.
|
Some errors occurred: E0121, E0223.
|
||||||
For more information about an error, try `rustc --explain E0121`.
|
For more information about an error, try `rustc --explain E0121`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue