mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-16 14:07:04 +00:00
Auto merge of #104437 - matthiaskrgr:rollup-n5jdg9v, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #103439 (Show note where the macro failed to match) - #103734 (Adjust stabilization version to 1.65.0 for wasi fds) - #104148 (Visit attributes of trait impl items during AST validation) - #104241 (Move most of unwind's build script to lib.rs) - #104258 (Deduce closure signature from a type alias `impl Trait`'s supertraits) - #104296 (Walk types more carefully in `ProhibitOpaqueTypes` visitor) - #104309 (Slightly improve error message for invalid identifier) - #104316 (Simplify suggestions for errors in generators.) - #104339 (Add `rustc_deny_explicit_impl`) Failed merges: - #103484 (Add `rust` to `let_underscore_lock` example) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
6d651a295e
@ -1051,6 +1051,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
|
||||
walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl);
|
||||
});
|
||||
walk_list!(self, visit_attribute, &item.attrs);
|
||||
return; // Avoid visiting again.
|
||||
}
|
||||
ItemKind::Impl(box Impl {
|
||||
@ -1168,7 +1169,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
});
|
||||
walk_list!(self, visit_assoc_item, items, AssocCtxt::Trait);
|
||||
walk_list!(self, visit_attribute, &item.attrs);
|
||||
return;
|
||||
return; // Avoid visiting again
|
||||
}
|
||||
ItemKind::Mod(unsafety, ref mod_kind) => {
|
||||
if let Unsafe::Yes(span) = unsafety {
|
||||
|
@ -1,4 +1,5 @@
|
||||
The `Sized` trait was implemented explicitly.
|
||||
A built-in trait was implemented explicitly. All implementations of the trait
|
||||
are provided automatically by the compiler.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
|
@ -384,3 +384,6 @@ parser_fn_ptr_with_generics = function pointer types may not have generic parame
|
||||
[true] the
|
||||
*[false] a
|
||||
} `for` parameter list
|
||||
|
||||
parser_invalid_identifier_with_leading_number = expected identifier, found number literal
|
||||
.label = identifiers cannot start with a number
|
||||
|
@ -76,6 +76,7 @@ pub(crate) use ParseResult::*;
|
||||
use crate::mbe::{macro_rules::Tracker, KleeneOp, TokenTree};
|
||||
|
||||
use rustc_ast::token::{self, DocComment, Nonterminal, NonterminalKind, Token};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
@ -86,6 +87,7 @@ use rustc_span::symbol::MacroRulesNormalizedIdent;
|
||||
use rustc_span::Span;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
use std::fmt::Display;
|
||||
|
||||
/// A unit within a matcher that a `MatcherPos` can refer to. Similar to (and derived from)
|
||||
/// `mbe::TokenTree`, but designed specifically for fast and easy traversal during matching.
|
||||
@ -96,7 +98,7 @@ use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
///
|
||||
/// This means a matcher can be represented by `&[MatcherLoc]`, and traversal mostly involves
|
||||
/// simply incrementing the current matcher position index by one.
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub(crate) enum MatcherLoc {
|
||||
Token {
|
||||
token: Token,
|
||||
@ -129,6 +131,46 @@ pub(crate) enum MatcherLoc {
|
||||
Eof,
|
||||
}
|
||||
|
||||
impl MatcherLoc {
|
||||
pub(super) fn span(&self) -> Option<Span> {
|
||||
match self {
|
||||
MatcherLoc::Token { token } => Some(token.span),
|
||||
MatcherLoc::Delimited => None,
|
||||
MatcherLoc::Sequence { .. } => None,
|
||||
MatcherLoc::SequenceKleeneOpNoSep { .. } => None,
|
||||
MatcherLoc::SequenceSep { .. } => None,
|
||||
MatcherLoc::SequenceKleeneOpAfterSep { .. } => None,
|
||||
MatcherLoc::MetaVarDecl { span, .. } => Some(*span),
|
||||
MatcherLoc::Eof => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for MatcherLoc {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
MatcherLoc::Token { token } | MatcherLoc::SequenceSep { separator: token } => {
|
||||
write!(f, "`{}`", pprust::token_to_string(token))
|
||||
}
|
||||
MatcherLoc::MetaVarDecl { bind, kind, .. } => {
|
||||
write!(f, "meta-variable `${bind}")?;
|
||||
if let Some(kind) = kind {
|
||||
write!(f, ":{}", kind)?;
|
||||
}
|
||||
write!(f, "`")?;
|
||||
Ok(())
|
||||
}
|
||||
MatcherLoc::Eof => f.write_str("end of macro"),
|
||||
|
||||
// These are not printed in the diagnostic
|
||||
MatcherLoc::Delimited => f.write_str("delimiter"),
|
||||
MatcherLoc::Sequence { .. } => f.write_str("sequence start"),
|
||||
MatcherLoc::SequenceKleeneOpNoSep { .. } => f.write_str("sequence end"),
|
||||
MatcherLoc::SequenceKleeneOpAfterSep { .. } => f.write_str("sequence end"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn compute_locs(matcher: &[TokenTree]) -> Vec<MatcherLoc> {
|
||||
fn inner(
|
||||
tts: &[TokenTree],
|
||||
@ -398,6 +440,10 @@ impl TtParser {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn has_no_remaining_items_for_step(&self) -> bool {
|
||||
self.cur_mps.is_empty()
|
||||
}
|
||||
|
||||
/// Process the matcher positions of `cur_mps` until it is empty. In the process, this will
|
||||
/// produce more mps in `next_mps` and `bb_mps`.
|
||||
///
|
||||
|
@ -337,7 +337,7 @@ fn expand_macro<'cx>(
|
||||
return result;
|
||||
}
|
||||
|
||||
let Some((token, label)) = tracker.best_failure else {
|
||||
let Some((token, label, remaining_matcher)) = tracker.best_failure else {
|
||||
return tracker.result.expect("must have encountered Error or ErrorReported");
|
||||
};
|
||||
|
||||
@ -351,6 +351,12 @@ fn expand_macro<'cx>(
|
||||
|
||||
annotate_doc_comment(&mut err, sess.source_map(), span);
|
||||
|
||||
if let Some(span) = remaining_matcher.span() {
|
||||
err.span_note(span, format!("while trying to match {remaining_matcher}"));
|
||||
} else {
|
||||
err.note(format!("while trying to match {remaining_matcher}"));
|
||||
}
|
||||
|
||||
// Check whether there's a missing comma in this macro call, like `println!("{}" a);`
|
||||
if let Some((arg, comma_span)) = arg.add_comma() {
|
||||
for lhs in lhses {
|
||||
@ -379,17 +385,22 @@ fn expand_macro<'cx>(
|
||||
}
|
||||
|
||||
/// The tracker used for the slow error path that collects useful info for diagnostics.
|
||||
struct CollectTrackerAndEmitter<'a, 'cx> {
|
||||
struct CollectTrackerAndEmitter<'a, 'cx, 'matcher> {
|
||||
cx: &'a mut ExtCtxt<'cx>,
|
||||
remaining_matcher: Option<&'matcher MatcherLoc>,
|
||||
/// Which arm's failure should we report? (the one furthest along)
|
||||
best_failure: Option<(Token, &'static str)>,
|
||||
best_failure: Option<(Token, &'static str, MatcherLoc)>,
|
||||
root_span: Span,
|
||||
result: Option<Box<dyn MacResult + 'cx>>,
|
||||
}
|
||||
|
||||
impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx> {
|
||||
fn before_match_loc(&mut self, _parser: &TtParser, _matcher: &'matcher MatcherLoc) {
|
||||
// Empty for now.
|
||||
impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx, 'matcher> {
|
||||
fn before_match_loc(&mut self, parser: &TtParser, matcher: &'matcher MatcherLoc) {
|
||||
if self.remaining_matcher.is_none()
|
||||
|| (parser.has_no_remaining_items_for_step() && *matcher != MatcherLoc::Eof)
|
||||
{
|
||||
self.remaining_matcher = Some(matcher);
|
||||
}
|
||||
}
|
||||
|
||||
fn after_arm(&mut self, result: &NamedParseResult) {
|
||||
@ -398,8 +409,16 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx>
|
||||
unreachable!("should not collect detailed info for successful macro match");
|
||||
}
|
||||
Failure(token, msg) => match self.best_failure {
|
||||
Some((ref best_token, _)) if best_token.span.lo() >= token.span.lo() => {}
|
||||
_ => self.best_failure = Some((token.clone(), msg)),
|
||||
Some((ref best_token, _, _)) if best_token.span.lo() >= token.span.lo() => {}
|
||||
_ => {
|
||||
self.best_failure = Some((
|
||||
token.clone(),
|
||||
msg,
|
||||
self.remaining_matcher
|
||||
.expect("must have collected matcher already")
|
||||
.clone(),
|
||||
))
|
||||
}
|
||||
},
|
||||
Error(err_sp, msg) => {
|
||||
let span = err_sp.substitute_dummy(self.root_span);
|
||||
@ -415,9 +434,9 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx>
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'cx> CollectTrackerAndEmitter<'a, 'cx> {
|
||||
impl<'a, 'cx> CollectTrackerAndEmitter<'a, 'cx, '_> {
|
||||
fn new(cx: &'a mut ExtCtxt<'cx>, root_span: Span) -> Self {
|
||||
Self { cx, best_failure: None, root_span, result: None }
|
||||
Self { cx, remaining_matcher: None, best_failure: None, root_span, result: None }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -691,6 +691,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
||||
rustc_allow_incoherent_impl, AttributeType::Normal, template!(Word), ErrorFollowing, @only_local: true,
|
||||
"#[rustc_allow_incoherent_impl] has to be added to all impl items of an incoherent inherent impl."
|
||||
),
|
||||
rustc_attr!(
|
||||
rustc_deny_explicit_impl, AttributeType::Normal, template!(Word), ErrorFollowing, @only_local: false,
|
||||
"#[rustc_deny_explicit_impl] enforces that a trait can have no user-provided impls"
|
||||
),
|
||||
rustc_attr!(
|
||||
rustc_has_incoherent_inherent_impls, AttributeType::Normal, template!(Word), ErrorFollowing,
|
||||
"#[rustc_has_incoherent_inherent_impls] allows the addition of incoherent inherent impls for \
|
||||
|
@ -5,10 +5,11 @@
|
||||
// done by the orphan and overlap modules. Then we build up various
|
||||
// mappings. That mapping code resides here.
|
||||
|
||||
use rustc_errors::struct_span_err;
|
||||
use rustc_errors::{error_code, struct_span_err};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::{self, TyCtxt, TypeVisitable};
|
||||
use rustc_span::sym;
|
||||
use rustc_trait_selection::traits;
|
||||
|
||||
mod builtin;
|
||||
@ -39,61 +40,26 @@ fn enforce_trait_manually_implementable(
|
||||
impl_def_id: LocalDefId,
|
||||
trait_def_id: DefId,
|
||||
) {
|
||||
let did = Some(trait_def_id);
|
||||
let li = tcx.lang_items();
|
||||
let impl_header_span = tcx.def_span(impl_def_id);
|
||||
|
||||
// Disallow *all* explicit impls of `Pointee`, `DiscriminantKind`, `Sized` and `Unsize` for now.
|
||||
if did == li.pointee_trait() {
|
||||
struct_span_err!(
|
||||
// Disallow *all* explicit impls of traits marked `#[rustc_deny_explicit_impl]`
|
||||
if tcx.has_attr(trait_def_id, sym::rustc_deny_explicit_impl) {
|
||||
let trait_name = tcx.item_name(trait_def_id);
|
||||
let mut err = struct_span_err!(
|
||||
tcx.sess,
|
||||
impl_header_span,
|
||||
E0322,
|
||||
"explicit impls for the `Pointee` trait are not permitted"
|
||||
)
|
||||
.span_label(impl_header_span, "impl of `Pointee` not allowed")
|
||||
.emit();
|
||||
return;
|
||||
}
|
||||
"explicit impls for the `{trait_name}` trait are not permitted"
|
||||
);
|
||||
err.span_label(impl_header_span, format!("impl of `{trait_name}` not allowed"));
|
||||
|
||||
if did == li.discriminant_kind_trait() {
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
impl_header_span,
|
||||
E0322,
|
||||
"explicit impls for the `DiscriminantKind` trait are not permitted"
|
||||
)
|
||||
.span_label(impl_header_span, "impl of `DiscriminantKind` not allowed")
|
||||
.emit();
|
||||
return;
|
||||
}
|
||||
// Maintain explicit error code for `Unsize`, since it has a useful
|
||||
// explanation about using `CoerceUnsized` instead.
|
||||
if Some(trait_def_id) == tcx.lang_items().unsize_trait() {
|
||||
err.code(error_code!(E0328));
|
||||
}
|
||||
|
||||
if did == li.sized_trait() {
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
impl_header_span,
|
||||
E0322,
|
||||
"explicit impls for the `Sized` trait are not permitted"
|
||||
)
|
||||
.span_label(impl_header_span, "impl of `Sized` not allowed")
|
||||
.emit();
|
||||
return;
|
||||
}
|
||||
|
||||
if did == li.unsize_trait() {
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
impl_header_span,
|
||||
E0328,
|
||||
"explicit impls for the `Unsize` trait are not permitted"
|
||||
)
|
||||
.span_label(impl_header_span, "impl of `Unsize` not allowed")
|
||||
.emit();
|
||||
return;
|
||||
}
|
||||
|
||||
if tcx.features().unboxed_closures {
|
||||
// the feature gate allows all Fn traits
|
||||
err.emit();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -173,34 +173,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
expected_ty: Ty<'tcx>,
|
||||
) -> (Option<ExpectedSig<'tcx>>, Option<ty::ClosureKind>) {
|
||||
match *expected_ty.kind() {
|
||||
ty::Opaque(def_id, substs) => {
|
||||
let bounds = self.tcx.bound_explicit_item_bounds(def_id);
|
||||
let sig =
|
||||
bounds.subst_iter_copied(self.tcx, substs).find_map(|(pred, span)| match pred
|
||||
.kind()
|
||||
.skip_binder()
|
||||
{
|
||||
ty::PredicateKind::Projection(proj_predicate) => self
|
||||
.deduce_sig_from_projection(
|
||||
Some(span),
|
||||
pred.kind().rebind(proj_predicate),
|
||||
),
|
||||
_ => None,
|
||||
});
|
||||
|
||||
let kind = bounds
|
||||
.0
|
||||
.iter()
|
||||
.filter_map(|(pred, _)| match pred.kind().skip_binder() {
|
||||
ty::PredicateKind::Trait(tp) => {
|
||||
self.tcx.fn_trait_kind_from_lang_item(tp.def_id())
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.fold(None, |best, cur| Some(best.map_or(cur, |best| cmp::min(best, cur))));
|
||||
trace!(?sig, ?kind);
|
||||
(sig, kind)
|
||||
}
|
||||
ty::Opaque(def_id, substs) => self.deduce_signature_from_predicates(
|
||||
self.tcx.bound_explicit_item_bounds(def_id).subst_iter_copied(self.tcx, substs),
|
||||
),
|
||||
ty::Dynamic(ref object_type, ..) => {
|
||||
let sig = object_type.projection_bounds().find_map(|pb| {
|
||||
let pb = pb.with_self_ty(self.tcx, self.tcx.types.trait_object_dummy_self);
|
||||
@ -211,7 +186,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
.and_then(|did| self.tcx.fn_trait_kind_from_lang_item(did));
|
||||
(sig, kind)
|
||||
}
|
||||
ty::Infer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid),
|
||||
ty::Infer(ty::TyVar(vid)) => self.deduce_signature_from_predicates(
|
||||
self.obligations_for_self_ty(vid).map(|obl| (obl.predicate, obl.cause.span)),
|
||||
),
|
||||
ty::FnPtr(sig) => {
|
||||
let expected_sig = ExpectedSig { cause_span: None, sig };
|
||||
(Some(expected_sig), Some(ty::ClosureKind::Fn))
|
||||
@ -220,19 +197,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn deduce_expectations_from_obligations(
|
||||
fn deduce_signature_from_predicates(
|
||||
&self,
|
||||
expected_vid: ty::TyVid,
|
||||
predicates: impl DoubleEndedIterator<Item = (ty::Predicate<'tcx>, Span)>,
|
||||
) -> (Option<ExpectedSig<'tcx>>, Option<ty::ClosureKind>) {
|
||||
let mut expected_sig = None;
|
||||
let mut expected_kind = None;
|
||||
|
||||
for obligation in traits::elaborate_obligations(
|
||||
for obligation in traits::elaborate_predicates_with_span(
|
||||
self.tcx,
|
||||
// Reverse the obligations here, since `elaborate_*` uses a stack,
|
||||
// and we want to keep inference generally in the same order of
|
||||
// the registered obligations.
|
||||
self.obligations_for_self_ty(expected_vid).rev().collect(),
|
||||
predicates.rev(),
|
||||
) {
|
||||
debug!(?obligation.predicate);
|
||||
let bound_predicate = obligation.predicate.kind();
|
||||
|
@ -1195,35 +1195,30 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool {
|
||||
struct ProhibitOpaqueTypes<'a, 'tcx> {
|
||||
cx: &'a LateContext<'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> ty::visit::TypeVisitor<'tcx> for ProhibitOpaqueTypes<'a, 'tcx> {
|
||||
struct ProhibitOpaqueTypes;
|
||||
impl<'tcx> ty::visit::TypeVisitor<'tcx> for ProhibitOpaqueTypes {
|
||||
type BreakTy = Ty<'tcx>;
|
||||
|
||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
match ty.kind() {
|
||||
ty::Opaque(..) => ControlFlow::Break(ty),
|
||||
// Consider opaque types within projections FFI-safe if they do not normalize
|
||||
// to more opaque types.
|
||||
ty::Projection(..) => {
|
||||
let ty = self.cx.tcx.normalize_erasing_regions(self.cx.param_env, ty);
|
||||
if !ty.has_opaque_types() {
|
||||
return ControlFlow::CONTINUE;
|
||||
}
|
||||
|
||||
// If `ty` is an opaque type directly then `super_visit_with` won't invoke
|
||||
// this function again.
|
||||
if ty.has_opaque_types() {
|
||||
self.visit_ty(ty)
|
||||
} else {
|
||||
ControlFlow::CONTINUE
|
||||
}
|
||||
}
|
||||
_ => ty.super_visit_with(self),
|
||||
if let ty::Opaque(..) = ty.kind() {
|
||||
ControlFlow::Break(ty)
|
||||
} else {
|
||||
ty.super_visit_with(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(ty) = ty.visit_with(&mut ProhibitOpaqueTypes { cx: self.cx }).break_value() {
|
||||
if let Some(ty) = self
|
||||
.cx
|
||||
.tcx
|
||||
.normalize_erasing_regions(self.cx.param_env, ty)
|
||||
.visit_with(&mut ProhibitOpaqueTypes)
|
||||
.break_value()
|
||||
{
|
||||
self.emit_ffi_unsafe_type_lint(ty, sp, fluent::lint_improper_ctypes_opaque, None);
|
||||
true
|
||||
} else {
|
||||
|
@ -6,7 +6,6 @@ use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts};
|
||||
use crate::ty::visit::{TypeVisitable, TypeVisitor};
|
||||
use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt};
|
||||
|
||||
use rustc_data_structures::captures::Captures;
|
||||
use rustc_data_structures::intern::{Interned, WithStableHash};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_macros::HashStable;
|
||||
@ -19,7 +18,7 @@ use std::fmt;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
use std::num::NonZeroUsize;
|
||||
use std::ops::ControlFlow;
|
||||
use std::ops::{ControlFlow, Deref};
|
||||
use std::slice;
|
||||
|
||||
/// An entity in the Rust type system, which can be one of
|
||||
@ -562,25 +561,86 @@ impl<T, U> EarlyBinder<(T, U)> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, 's, T: IntoIterator<Item = I>, I: TypeFoldable<'tcx>> EarlyBinder<T> {
|
||||
impl<'tcx, 's, I: IntoIterator> EarlyBinder<I>
|
||||
where
|
||||
I::Item: TypeFoldable<'tcx>,
|
||||
{
|
||||
pub fn subst_iter(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
substs: &'s [GenericArg<'tcx>],
|
||||
) -> impl Iterator<Item = I> + Captures<'s> + Captures<'tcx> {
|
||||
self.0.into_iter().map(move |t| EarlyBinder(t).subst(tcx, substs))
|
||||
) -> SubstIter<'s, 'tcx, I> {
|
||||
SubstIter { it: self.0.into_iter(), tcx, substs }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, 's, 'a, T: IntoIterator<Item = &'a I>, I: Copy + TypeFoldable<'tcx> + 'a>
|
||||
EarlyBinder<T>
|
||||
pub struct SubstIter<'s, 'tcx, I: IntoIterator> {
|
||||
it: I::IntoIter,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
substs: &'s [GenericArg<'tcx>],
|
||||
}
|
||||
|
||||
impl<'tcx, I: IntoIterator> Iterator for SubstIter<'_, 'tcx, I>
|
||||
where
|
||||
I::Item: TypeFoldable<'tcx>,
|
||||
{
|
||||
type Item = I::Item;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
Some(EarlyBinder(self.it.next()?).subst(self.tcx, self.substs))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, I: IntoIterator> DoubleEndedIterator for SubstIter<'_, 'tcx, I>
|
||||
where
|
||||
I::IntoIter: DoubleEndedIterator,
|
||||
I::Item: TypeFoldable<'tcx>,
|
||||
{
|
||||
fn next_back(&mut self) -> Option<Self::Item> {
|
||||
Some(EarlyBinder(self.it.next_back()?).subst(self.tcx, self.substs))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, 's, I: IntoIterator> EarlyBinder<I>
|
||||
where
|
||||
I::Item: Deref,
|
||||
<I::Item as Deref>::Target: Copy + TypeFoldable<'tcx>,
|
||||
{
|
||||
pub fn subst_iter_copied(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
substs: &'s [GenericArg<'tcx>],
|
||||
) -> impl Iterator<Item = I> + Captures<'s> + Captures<'tcx> + Captures<'a> {
|
||||
self.0.into_iter().map(move |t| EarlyBinder(*t).subst(tcx, substs))
|
||||
) -> SubstIterCopied<'s, 'tcx, I> {
|
||||
SubstIterCopied { it: self.0.into_iter(), tcx, substs }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SubstIterCopied<'a, 'tcx, I: IntoIterator> {
|
||||
it: I::IntoIter,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
substs: &'a [GenericArg<'tcx>],
|
||||
}
|
||||
|
||||
impl<'tcx, I: IntoIterator> Iterator for SubstIterCopied<'_, 'tcx, I>
|
||||
where
|
||||
I::Item: Deref,
|
||||
<I::Item as Deref>::Target: Copy + TypeFoldable<'tcx>,
|
||||
{
|
||||
type Item = <I::Item as Deref>::Target;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
Some(EarlyBinder(*self.it.next()?).subst(self.tcx, self.substs))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, I: IntoIterator> DoubleEndedIterator for SubstIterCopied<'_, 'tcx, I>
|
||||
where
|
||||
I::IntoIter: DoubleEndedIterator,
|
||||
I::Item: Deref,
|
||||
<I::Item as Deref>::Target: Copy + TypeFoldable<'tcx>,
|
||||
{
|
||||
fn next_back(&mut self) -> Option<Self::Item> {
|
||||
Some(EarlyBinder(*self.it.next_back()?).subst(self.tcx, self.substs))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1205,6 +1205,14 @@ pub(crate) struct SelfParamNotFirst {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parser_invalid_identifier_with_leading_number)]
|
||||
pub(crate) struct InvalidIdentiferStartsWithNumber {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parser_const_generic_without_braces)]
|
||||
pub(crate) struct ConstGenericWithoutBraces {
|
||||
|
@ -10,8 +10,8 @@ use super::{
|
||||
use crate::errors::{
|
||||
AssignmentElseNotAllowed, CompoundAssignmentExpressionInLet, ConstLetMutuallyExclusive,
|
||||
DocCommentDoesNotDocumentAnything, ExpectedStatementAfterOuterAttr, InvalidCurlyInLetElse,
|
||||
InvalidExpressionInLetElse, InvalidVariableDeclaration, InvalidVariableDeclarationSub,
|
||||
WrapExpressionInParentheses,
|
||||
InvalidExpressionInLetElse, InvalidIdentiferStartsWithNumber, InvalidVariableDeclaration,
|
||||
InvalidVariableDeclarationSub, WrapExpressionInParentheses,
|
||||
};
|
||||
use crate::maybe_whole;
|
||||
|
||||
@ -264,6 +264,7 @@ impl<'a> Parser<'a> {
|
||||
self.bump();
|
||||
}
|
||||
|
||||
self.report_invalid_identifier_error()?;
|
||||
let (pat, colon) = self.parse_pat_before_ty(None, RecoverComma::Yes, "`let` bindings")?;
|
||||
|
||||
let (err, ty) = if colon {
|
||||
@ -355,6 +356,17 @@ impl<'a> Parser<'a> {
|
||||
Ok(P(ast::Local { ty, pat, kind, id: DUMMY_NODE_ID, span: lo.to(hi), attrs, tokens: None }))
|
||||
}
|
||||
|
||||
/// report error for `let 1x = 123`
|
||||
pub fn report_invalid_identifier_error(&mut self) -> PResult<'a, ()> {
|
||||
if let token::Literal(lit) = self.token.uninterpolate().kind &&
|
||||
let Err(_) = rustc_ast::Lit::from_token(&self.token) &&
|
||||
(lit.kind == token::LitKind::Integer || lit.kind == token::LitKind::Float) &&
|
||||
self.look_ahead(1, |t| matches!(t.kind, token::Eq) || matches!(t.kind, token::Colon ) ) {
|
||||
return Err(self.sess.create_err(InvalidIdentiferStartsWithNumber { span: self.token.span }));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check_let_else_init_bool_expr(&self, init: &ast::Expr) {
|
||||
if let ast::ExprKind::Binary(op, ..) = init.kind {
|
||||
if op.node.lazy() {
|
||||
|
@ -1210,6 +1210,7 @@ symbols! {
|
||||
rustc_deallocator,
|
||||
rustc_def_path,
|
||||
rustc_default_body_unstable,
|
||||
rustc_deny_explicit_impl,
|
||||
rustc_diagnostic_item,
|
||||
rustc_diagnostic_macros,
|
||||
rustc_dirty,
|
||||
|
@ -44,7 +44,7 @@ use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
#[derive(Debug)]
|
||||
pub enum GeneratorInteriorOrUpvar {
|
||||
// span of interior type
|
||||
Interior(Span),
|
||||
Interior(Span, Option<(Option<Span>, Span, Option<hir::HirId>, Option<Span>)>),
|
||||
// span of upvar
|
||||
Upvar(Span),
|
||||
}
|
||||
@ -283,7 +283,6 @@ pub trait TypeErrCtxtExt<'tcx> {
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
interior_or_upvar_span: GeneratorInteriorOrUpvar,
|
||||
interior_extra_info: Option<(Option<Span>, Span, Option<hir::HirId>, Option<Span>)>,
|
||||
is_async: bool,
|
||||
outer_generator: Option<DefId>,
|
||||
trait_pred: ty::TraitPredicate<'tcx>,
|
||||
@ -2003,17 +2002,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
.as_local()
|
||||
.and_then(|def_id| hir.maybe_body_owned_by(def_id))
|
||||
.map(|body_id| hir.body(body_id));
|
||||
let is_async = match generator_did.as_local() {
|
||||
Some(_) => generator_body
|
||||
.and_then(|body| body.generator_kind())
|
||||
.map(|generator_kind| matches!(generator_kind, hir::GeneratorKind::Async(..)))
|
||||
.unwrap_or(false),
|
||||
None => self
|
||||
.tcx
|
||||
.generator_kind(generator_did)
|
||||
.map(|generator_kind| matches!(generator_kind, hir::GeneratorKind::Async(..)))
|
||||
.unwrap_or(false),
|
||||
};
|
||||
let is_async = self
|
||||
.tcx
|
||||
.generator_kind(generator_did)
|
||||
.map(|generator_kind| matches!(generator_kind, hir::GeneratorKind::Async(..)))
|
||||
.unwrap_or(false);
|
||||
let mut visitor = AwaitsVisitor::default();
|
||||
if let Some(body) = generator_body {
|
||||
visitor.visit_body(body);
|
||||
@ -2043,61 +2036,60 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
eq
|
||||
};
|
||||
|
||||
let mut interior_or_upvar_span = None;
|
||||
let mut interior_extra_info = None;
|
||||
|
||||
// Get the typeck results from the infcx if the generator is the function we are currently
|
||||
// type-checking; otherwise, get them by performing a query. This is needed to avoid
|
||||
// cycles. If we can't use resolved types because the generator comes from another crate,
|
||||
// we still provide a targeted error but without all the relevant spans.
|
||||
let generator_data: Option<GeneratorData<'tcx, '_>> = match &self.typeck_results {
|
||||
Some(t) if t.hir_owner.to_def_id() == generator_did_root => {
|
||||
Some(GeneratorData::Local(&t))
|
||||
}
|
||||
let generator_data = match &self.typeck_results {
|
||||
Some(t) if t.hir_owner.to_def_id() == generator_did_root => GeneratorData::Local(&t),
|
||||
_ if generator_did.is_local() => {
|
||||
Some(GeneratorData::Local(self.tcx.typeck(generator_did.expect_local())))
|
||||
GeneratorData::Local(self.tcx.typeck(generator_did.expect_local()))
|
||||
}
|
||||
_ => self
|
||||
.tcx
|
||||
.generator_diagnostic_data(generator_did)
|
||||
.as_ref()
|
||||
.map(|generator_diag_data| GeneratorData::Foreign(generator_diag_data)),
|
||||
_ if let Some(generator_diag_data) = self.tcx.generator_diagnostic_data(generator_did) => {
|
||||
GeneratorData::Foreign(generator_diag_data)
|
||||
}
|
||||
_ => return false,
|
||||
};
|
||||
|
||||
if let Some(generator_data) = generator_data.as_ref() {
|
||||
interior_or_upvar_span =
|
||||
generator_data.try_get_upvar_span(&self, generator_did, ty_matches);
|
||||
let mut interior_or_upvar_span = None;
|
||||
|
||||
// The generator interior types share the same binders
|
||||
if let Some(cause) =
|
||||
generator_data.get_generator_interior_types().skip_binder().iter().find(
|
||||
|ty::GeneratorInteriorTypeCause { ty, .. }| {
|
||||
ty_matches(generator_data.get_generator_interior_types().rebind(*ty))
|
||||
},
|
||||
)
|
||||
{
|
||||
let from_awaited_ty = generator_data.get_from_await_ty(visitor, hir, ty_matches);
|
||||
let ty::GeneratorInteriorTypeCause { span, scope_span, yield_span, expr, .. } =
|
||||
cause;
|
||||
let from_awaited_ty = generator_data.get_from_await_ty(visitor, hir, ty_matches);
|
||||
debug!(?from_awaited_ty);
|
||||
|
||||
interior_or_upvar_span = Some(GeneratorInteriorOrUpvar::Interior(*span));
|
||||
interior_extra_info = Some((*scope_span, *yield_span, *expr, from_awaited_ty));
|
||||
}
|
||||
// The generator interior types share the same binders
|
||||
if let Some(cause) =
|
||||
generator_data.get_generator_interior_types().skip_binder().iter().find(
|
||||
|ty::GeneratorInteriorTypeCause { ty, .. }| {
|
||||
ty_matches(generator_data.get_generator_interior_types().rebind(*ty))
|
||||
},
|
||||
)
|
||||
{
|
||||
let ty::GeneratorInteriorTypeCause { span, scope_span, yield_span, expr, .. } = cause;
|
||||
|
||||
if interior_or_upvar_span.is_none() && generator_data.is_foreign() {
|
||||
interior_or_upvar_span = Some(GeneratorInteriorOrUpvar::Interior(span));
|
||||
}
|
||||
interior_or_upvar_span = Some(GeneratorInteriorOrUpvar::Interior(
|
||||
*span,
|
||||
Some((*scope_span, *yield_span, *expr, from_awaited_ty)),
|
||||
));
|
||||
}
|
||||
|
||||
if interior_or_upvar_span.is_none() {
|
||||
interior_or_upvar_span =
|
||||
generator_data.try_get_upvar_span(&self, generator_did, ty_matches);
|
||||
}
|
||||
|
||||
if interior_or_upvar_span.is_none() && generator_data.is_foreign() {
|
||||
interior_or_upvar_span = Some(GeneratorInteriorOrUpvar::Interior(span, None));
|
||||
}
|
||||
|
||||
debug!(?interior_or_upvar_span);
|
||||
if let Some(interior_or_upvar_span) = interior_or_upvar_span {
|
||||
let typeck_results = generator_data.and_then(|generator_data| match generator_data {
|
||||
let typeck_results = match generator_data {
|
||||
GeneratorData::Local(typeck_results) => Some(typeck_results),
|
||||
GeneratorData::Foreign(_) => None,
|
||||
});
|
||||
};
|
||||
self.note_obligation_cause_for_async_await(
|
||||
err,
|
||||
interior_or_upvar_span,
|
||||
interior_extra_info,
|
||||
is_async,
|
||||
outer_generator,
|
||||
trait_ref,
|
||||
@ -2119,7 +2111,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
interior_or_upvar_span: GeneratorInteriorOrUpvar,
|
||||
interior_extra_info: Option<(Option<Span>, Span, Option<hir::HirId>, Option<Span>)>,
|
||||
is_async: bool,
|
||||
outer_generator: Option<DefId>,
|
||||
trait_pred: ty::TraitPredicate<'tcx>,
|
||||
@ -2241,7 +2232,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
}
|
||||
};
|
||||
match interior_or_upvar_span {
|
||||
GeneratorInteriorOrUpvar::Interior(interior_span) => {
|
||||
GeneratorInteriorOrUpvar::Interior(interior_span, interior_extra_info) => {
|
||||
if let Some((scope_span, yield_span, expr, from_awaited_ty)) = interior_extra_info {
|
||||
if let Some(await_span) = from_awaited_ty {
|
||||
// The type causing this obligation is one being awaited at await_span.
|
||||
|
@ -96,6 +96,7 @@ unsafe impl<T: Sync + ?Sized> Send for &T {}
|
||||
)]
|
||||
#[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
|
||||
#[rustc_specialization_trait]
|
||||
#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)]
|
||||
pub trait Sized {
|
||||
// Empty.
|
||||
}
|
||||
@ -127,6 +128,7 @@ pub trait Sized {
|
||||
/// [nomicon-coerce]: ../../nomicon/coercions.html
|
||||
#[unstable(feature = "unsize", issue = "27732")]
|
||||
#[lang = "unsize"]
|
||||
#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)]
|
||||
pub trait Unsize<T: ?Sized> {
|
||||
// Empty.
|
||||
}
|
||||
@ -693,6 +695,7 @@ impl<T: ?Sized> StructuralEq for PhantomData<T> {}
|
||||
reason = "this trait is unlikely to ever be stabilized, use `mem::discriminant` instead"
|
||||
)]
|
||||
#[lang = "discriminant_kind"]
|
||||
#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)]
|
||||
pub trait DiscriminantKind {
|
||||
/// The type of the discriminant, which must satisfy the trait
|
||||
/// bounds required by `mem::Discriminant`.
|
||||
@ -793,6 +796,7 @@ impl<T: ?Sized> Unpin for *mut T {}
|
||||
#[lang = "destruct"]
|
||||
#[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)]
|
||||
#[const_trait]
|
||||
#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)]
|
||||
pub trait Destruct {}
|
||||
|
||||
/// A marker for tuple types.
|
||||
@ -802,6 +806,7 @@ pub trait Destruct {}
|
||||
#[unstable(feature = "tuple_trait", issue = "none")]
|
||||
#[lang = "tuple_trait"]
|
||||
#[rustc_on_unimplemented(message = "`{Self}` is not a tuple")]
|
||||
#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)]
|
||||
pub trait Tuple {}
|
||||
|
||||
/// Implementations of `Copy` for primitive types.
|
||||
|
@ -50,6 +50,7 @@ use crate::hash::{Hash, Hasher};
|
||||
///
|
||||
/// [`to_raw_parts`]: *const::to_raw_parts
|
||||
#[lang = "pointee_trait"]
|
||||
#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)]
|
||||
pub trait Pointee {
|
||||
/// The type for metadata in pointers and references to `Self`.
|
||||
#[lang = "metadata_type"]
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! WASI-specific extensions to general I/O primitives.
|
||||
|
||||
#![stable(feature = "io_safety", since = "1.63.0")]
|
||||
#![stable(feature = "io_safety_wasi", since = "1.65.0")]
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
#[stable(feature = "io_safety_wasi", since = "1.65.0")]
|
||||
pub use crate::os::fd::*;
|
||||
|
@ -21,29 +21,5 @@ fn main() {
|
||||
if has_unwind {
|
||||
println!("cargo:rustc-cfg=feature=\"system-llvm-libunwind\"");
|
||||
}
|
||||
} else if target.contains("freebsd") {
|
||||
println!("cargo:rustc-link-lib=gcc_s");
|
||||
} else if target.contains("netbsd") {
|
||||
println!("cargo:rustc-link-lib=gcc_s");
|
||||
} else if target.contains("openbsd") {
|
||||
if target.contains("sparc64") {
|
||||
println!("cargo:rustc-link-lib=gcc");
|
||||
} else {
|
||||
println!("cargo:rustc-link-lib=c++abi");
|
||||
}
|
||||
} else if target.contains("solaris") {
|
||||
println!("cargo:rustc-link-lib=gcc_s");
|
||||
} else if target.contains("illumos") {
|
||||
println!("cargo:rustc-link-lib=gcc_s");
|
||||
} else if target.contains("dragonfly") {
|
||||
println!("cargo:rustc-link-lib=gcc_pic");
|
||||
} else if target.ends_with("pc-windows-gnu") {
|
||||
// This is handled in the target spec with late_link_args_[static|dynamic]
|
||||
} else if target.contains("uwp-windows-gnu") {
|
||||
println!("cargo:rustc-link-lib=unwind");
|
||||
} else if target.contains("haiku") {
|
||||
println!("cargo:rustc-link-lib=gcc_s");
|
||||
} else if target.contains("redox") {
|
||||
// redox is handled in lib.rs
|
||||
}
|
||||
}
|
||||
|
@ -103,3 +103,27 @@ extern "C" {}
|
||||
#[cfg(all(target_vendor = "fortanix", target_env = "sgx"))]
|
||||
#[link(name = "unwind", kind = "static", modifiers = "-bundle")]
|
||||
extern "C" {}
|
||||
|
||||
#[cfg(any(target_os = "freebsd", target_os = "netbsd"))]
|
||||
#[link(name = "gcc_s")]
|
||||
extern "C" {}
|
||||
|
||||
#[cfg(all(target_os = "openbsd", target_arch = "sparc64"))]
|
||||
#[link(name = "gcc")]
|
||||
extern "C" {}
|
||||
|
||||
#[cfg(all(target_os = "openbsd", not(target_arch = "sparc64")))]
|
||||
#[link(name = "c++abi")]
|
||||
extern "C" {}
|
||||
|
||||
#[cfg(any(target_os = "solaris", target_os = "illumos"))]
|
||||
#[link(name = "gcc_s")]
|
||||
extern "C" {}
|
||||
|
||||
#[cfg(target_os = "dragonfly")]
|
||||
#[link(name = "gcc_pic")]
|
||||
extern "C" {}
|
||||
|
||||
#[cfg(target_os = "haiku")]
|
||||
#[link(name = "gcc_s")]
|
||||
extern "C" {}
|
||||
|
@ -3,6 +3,8 @@ error: no rules expected the token `,`
|
||||
|
|
||||
LL | vec![,];
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
||||
= note: while trying to match end of macro
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -53,6 +53,12 @@ LL | macro_rules! gimme_a_const {
|
||||
...
|
||||
LL | let _fail = Example::<gimme_a_const!()>;
|
||||
| ^^^^^^^^^^^^^^^^ missing tokens in macro arguments
|
||||
|
|
||||
note: while trying to match meta-variable `$rusty:ident`
|
||||
--> $DIR/macro-fail.rs:28:8
|
||||
|
|
||||
LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }}
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error[E0747]: type provided when a constant was expected
|
||||
--> $DIR/macro-fail.rs:14:33
|
||||
|
@ -3,12 +3,24 @@ error: no rules expected the token `r#async`
|
||||
|
|
||||
LL | r#async = consumes_async!(r#async);
|
||||
| ^^^^^^^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match `async`
|
||||
--> $DIR/auxiliary/edition-kw-macro-2015.rs:17:6
|
||||
|
|
||||
LL | (async) => (1)
|
||||
| ^^^^^
|
||||
|
||||
error: no rules expected the token `async`
|
||||
--> $DIR/edition-keywords-2015-2015-parsing.rs:17:35
|
||||
|
|
||||
LL | r#async = consumes_async_raw!(async);
|
||||
| ^^^^^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match `r#async`
|
||||
--> $DIR/auxiliary/edition-kw-macro-2015.rs:22:6
|
||||
|
|
||||
LL | (r#async) => (1)
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -3,12 +3,24 @@ error: no rules expected the token `r#async`
|
||||
|
|
||||
LL | r#async = consumes_async!(r#async);
|
||||
| ^^^^^^^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match `async`
|
||||
--> $DIR/auxiliary/edition-kw-macro-2018.rs:17:6
|
||||
|
|
||||
LL | (async) => (1)
|
||||
| ^^^^^
|
||||
|
||||
error: no rules expected the token `async`
|
||||
--> $DIR/edition-keywords-2015-2018-parsing.rs:17:35
|
||||
|
|
||||
LL | r#async = consumes_async_raw!(async);
|
||||
| ^^^^^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match `r#async`
|
||||
--> $DIR/auxiliary/edition-kw-macro-2018.rs:22:6
|
||||
|
|
||||
LL | (r#async) => (1)
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -25,12 +25,24 @@ error: no rules expected the token `r#async`
|
||||
|
|
||||
LL | r#async = consumes_async!(r#async);
|
||||
| ^^^^^^^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match `async`
|
||||
--> $DIR/auxiliary/edition-kw-macro-2015.rs:17:6
|
||||
|
|
||||
LL | (async) => (1)
|
||||
| ^^^^^
|
||||
|
||||
error: no rules expected the token `async`
|
||||
--> $DIR/edition-keywords-2018-2015-parsing.rs:21:35
|
||||
|
|
||||
LL | r#async = consumes_async_raw!(async);
|
||||
| ^^^^^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match `r#async`
|
||||
--> $DIR/auxiliary/edition-kw-macro-2015.rs:22:6
|
||||
|
|
||||
LL | (r#async) => (1)
|
||||
| ^^^^^^^
|
||||
|
||||
error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||`
|
||||
--> $DIR/auxiliary/edition-kw-macro-2015.rs:27:23
|
||||
|
@ -25,12 +25,24 @@ error: no rules expected the token `r#async`
|
||||
|
|
||||
LL | r#async = consumes_async!(r#async);
|
||||
| ^^^^^^^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match `async`
|
||||
--> $DIR/auxiliary/edition-kw-macro-2018.rs:17:6
|
||||
|
|
||||
LL | (async) => (1)
|
||||
| ^^^^^
|
||||
|
||||
error: no rules expected the token `async`
|
||||
--> $DIR/edition-keywords-2018-2018-parsing.rs:21:35
|
||||
|
|
||||
LL | r#async = consumes_async_raw!(async);
|
||||
| ^^^^^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match `r#async`
|
||||
--> $DIR/auxiliary/edition-kw-macro-2018.rs:22:6
|
||||
|
|
||||
LL | (r#async) => (1)
|
||||
| ^^^^^^^
|
||||
|
||||
error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||`
|
||||
--> $DIR/auxiliary/edition-kw-macro-2018.rs:27:23
|
||||
|
@ -6,6 +6,12 @@ LL | macro_rules! one_arg_macro {
|
||||
...
|
||||
LL | one_arg_macro!(/**/);
|
||||
| ^^^^^^^^^^^^^^^^^^^^ missing tokens in macro arguments
|
||||
|
|
||||
note: while trying to match meta-variable `$fmt:expr`
|
||||
--> $DIR/empty-comment.rs:6:6
|
||||
|
|
||||
LL | ($fmt:expr) => (print!(concat!($fmt, "\n")));
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -3,6 +3,8 @@ error: no rules expected the token `@`
|
||||
|
|
||||
LL | panic!(@);
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
||||
= note: while trying to match end of macro
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
15
src/test/ui/impl-trait/deduce-signature-from-supertrait.rs
Normal file
15
src/test/ui/impl-trait/deduce-signature-from-supertrait.rs
Normal file
@ -0,0 +1,15 @@
|
||||
// check-pass
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
trait SuperExpectation: Fn(i32) {}
|
||||
|
||||
impl<T: Fn(i32)> SuperExpectation for T {}
|
||||
|
||||
type Foo = impl SuperExpectation;
|
||||
|
||||
fn main() {
|
||||
let _: Foo = |x| {
|
||||
let _ = x.to_string();
|
||||
};
|
||||
}
|
@ -6,6 +6,12 @@ LL | macro_rules! one_arg_macro {
|
||||
...
|
||||
LL | one_arg_macro!();
|
||||
| ^^^^^^^^^^^^^^^^ missing tokens in macro arguments
|
||||
|
|
||||
note: while trying to match meta-variable `$fmt:expr`
|
||||
--> $DIR/issue-7970a.rs:2:6
|
||||
|
|
||||
LL | ($fmt:expr) => (print!(concat!($fmt, "\n")));
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
41
src/test/ui/lint/opaque-ty-ffi-normalization-cycle.rs
Normal file
41
src/test/ui/lint/opaque-ty-ffi-normalization-cycle.rs
Normal file
@ -0,0 +1,41 @@
|
||||
#![feature(type_alias_impl_trait)]
|
||||
#![allow(unused)]
|
||||
#![deny(improper_ctypes)]
|
||||
|
||||
pub trait TraitA {
|
||||
type Assoc;
|
||||
}
|
||||
|
||||
impl TraitA for u32 {
|
||||
type Assoc = u32;
|
||||
}
|
||||
|
||||
pub trait TraitB {
|
||||
type Assoc;
|
||||
}
|
||||
|
||||
impl<T> TraitB for T
|
||||
where
|
||||
T: TraitA,
|
||||
{
|
||||
type Assoc = <T as TraitA>::Assoc;
|
||||
}
|
||||
|
||||
type AliasA = impl TraitA<Assoc = u32>;
|
||||
|
||||
type AliasB = impl TraitB;
|
||||
|
||||
fn use_of_a() -> AliasA {
|
||||
3
|
||||
}
|
||||
|
||||
fn use_of_b() -> AliasB {
|
||||
3
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
fn lint_me() -> <AliasB as TraitB>::Assoc;
|
||||
//~^ ERROR `extern` block uses type `AliasB`, which is not FFI-safe
|
||||
}
|
||||
|
||||
fn main() {}
|
15
src/test/ui/lint/opaque-ty-ffi-normalization-cycle.stderr
Normal file
15
src/test/ui/lint/opaque-ty-ffi-normalization-cycle.stderr
Normal file
@ -0,0 +1,15 @@
|
||||
error: `extern` block uses type `AliasB`, which is not FFI-safe
|
||||
--> $DIR/opaque-ty-ffi-normalization-cycle.rs:37:21
|
||||
|
|
||||
LL | fn lint_me() -> <AliasB as TraitB>::Assoc;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= note: opaque types have no C equivalent
|
||||
note: the lint level is defined here
|
||||
--> $DIR/opaque-ty-ffi-normalization-cycle.rs:3:9
|
||||
|
|
||||
LL | #![deny(improper_ctypes)]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -17,6 +17,8 @@ LL | assert!(true, "whatever" blah);
|
||||
| -^^^^ no rules expected this token in macro call
|
||||
| |
|
||||
| help: missing comma here
|
||||
|
|
||||
= note: while trying to match sequence start
|
||||
|
||||
error: unexpected string literal
|
||||
--> $DIR/assert-trailing-junk.rs:18:18
|
||||
@ -33,6 +35,8 @@ LL | assert!(true "whatever" blah);
|
||||
| -^^^^ no rules expected this token in macro call
|
||||
| |
|
||||
| help: missing comma here
|
||||
|
|
||||
= note: while trying to match sequence start
|
||||
|
||||
error: macro requires an expression as an argument
|
||||
--> $DIR/assert-trailing-junk.rs:22:5
|
||||
|
@ -17,6 +17,8 @@ LL | assert!(true, "whatever" blah);
|
||||
| -^^^^ no rules expected this token in macro call
|
||||
| |
|
||||
| help: missing comma here
|
||||
|
|
||||
= note: while trying to match sequence start
|
||||
|
||||
error: unexpected string literal
|
||||
--> $DIR/assert-trailing-junk.rs:18:18
|
||||
@ -33,6 +35,8 @@ LL | assert!(true "whatever" blah);
|
||||
| -^^^^ no rules expected this token in macro call
|
||||
| |
|
||||
| help: missing comma here
|
||||
|
|
||||
= note: while trying to match sequence start
|
||||
|
||||
error: macro requires an expression as an argument
|
||||
--> $DIR/assert-trailing-junk.rs:22:5
|
||||
|
@ -12,6 +12,8 @@ LL | macro_rules! foo {
|
||||
...
|
||||
LL | foo!(a?);
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
||||
= note: while trying to match sequence end
|
||||
|
||||
error: no rules expected the token `?`
|
||||
--> $DIR/macro-at-most-once-rep-2015.rs:26:11
|
||||
@ -21,6 +23,8 @@ LL | macro_rules! foo {
|
||||
...
|
||||
LL | foo!(a?a);
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
||||
= note: while trying to match sequence end
|
||||
|
||||
error: no rules expected the token `?`
|
||||
--> $DIR/macro-at-most-once-rep-2015.rs:27:11
|
||||
@ -30,6 +34,8 @@ LL | macro_rules! foo {
|
||||
...
|
||||
LL | foo!(a?a?a);
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
||||
= note: while trying to match sequence end
|
||||
|
||||
error: unexpected end of macro invocation
|
||||
--> $DIR/macro-at-most-once-rep-2015.rs:29:5
|
||||
@ -39,6 +45,12 @@ LL | macro_rules! barplus {
|
||||
...
|
||||
LL | barplus!();
|
||||
| ^^^^^^^^^^ missing tokens in macro arguments
|
||||
|
|
||||
note: while trying to match `+`
|
||||
--> $DIR/macro-at-most-once-rep-2015.rs:15:11
|
||||
|
|
||||
LL | ($(a)?+) => {}; // ok. matches "a+" and "+"
|
||||
| ^
|
||||
|
||||
error: unexpected end of macro invocation
|
||||
--> $DIR/macro-at-most-once-rep-2015.rs:30:15
|
||||
@ -48,6 +60,12 @@ LL | macro_rules! barplus {
|
||||
...
|
||||
LL | barplus!(a);
|
||||
| ^ missing tokens in macro arguments
|
||||
|
|
||||
note: while trying to match `+`
|
||||
--> $DIR/macro-at-most-once-rep-2015.rs:15:11
|
||||
|
|
||||
LL | ($(a)?+) => {}; // ok. matches "a+" and "+"
|
||||
| ^
|
||||
|
||||
error: no rules expected the token `?`
|
||||
--> $DIR/macro-at-most-once-rep-2015.rs:31:15
|
||||
@ -57,6 +75,12 @@ LL | macro_rules! barplus {
|
||||
...
|
||||
LL | barplus!(a?);
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match `+`
|
||||
--> $DIR/macro-at-most-once-rep-2015.rs:15:11
|
||||
|
|
||||
LL | ($(a)?+) => {}; // ok. matches "a+" and "+"
|
||||
| ^
|
||||
|
||||
error: no rules expected the token `?`
|
||||
--> $DIR/macro-at-most-once-rep-2015.rs:32:15
|
||||
@ -66,6 +90,12 @@ LL | macro_rules! barplus {
|
||||
...
|
||||
LL | barplus!(a?a);
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match `+`
|
||||
--> $DIR/macro-at-most-once-rep-2015.rs:15:11
|
||||
|
|
||||
LL | ($(a)?+) => {}; // ok. matches "a+" and "+"
|
||||
| ^
|
||||
|
||||
error: unexpected end of macro invocation
|
||||
--> $DIR/macro-at-most-once-rep-2015.rs:36:5
|
||||
@ -75,6 +105,12 @@ LL | macro_rules! barstar {
|
||||
...
|
||||
LL | barstar!();
|
||||
| ^^^^^^^^^^ missing tokens in macro arguments
|
||||
|
|
||||
note: while trying to match `*`
|
||||
--> $DIR/macro-at-most-once-rep-2015.rs:19:11
|
||||
|
|
||||
LL | ($(a)?*) => {}; // ok. matches "a*" and "*"
|
||||
| ^
|
||||
|
||||
error: unexpected end of macro invocation
|
||||
--> $DIR/macro-at-most-once-rep-2015.rs:37:15
|
||||
@ -84,6 +120,12 @@ LL | macro_rules! barstar {
|
||||
...
|
||||
LL | barstar!(a);
|
||||
| ^ missing tokens in macro arguments
|
||||
|
|
||||
note: while trying to match `*`
|
||||
--> $DIR/macro-at-most-once-rep-2015.rs:19:11
|
||||
|
|
||||
LL | ($(a)?*) => {}; // ok. matches "a*" and "*"
|
||||
| ^
|
||||
|
||||
error: no rules expected the token `?`
|
||||
--> $DIR/macro-at-most-once-rep-2015.rs:38:15
|
||||
@ -93,6 +135,12 @@ LL | macro_rules! barstar {
|
||||
...
|
||||
LL | barstar!(a?);
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match `*`
|
||||
--> $DIR/macro-at-most-once-rep-2015.rs:19:11
|
||||
|
|
||||
LL | ($(a)?*) => {}; // ok. matches "a*" and "*"
|
||||
| ^
|
||||
|
||||
error: no rules expected the token `?`
|
||||
--> $DIR/macro-at-most-once-rep-2015.rs:39:15
|
||||
@ -102,6 +150,12 @@ LL | macro_rules! barstar {
|
||||
...
|
||||
LL | barstar!(a?a);
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match `*`
|
||||
--> $DIR/macro-at-most-once-rep-2015.rs:19:11
|
||||
|
|
||||
LL | ($(a)?*) => {}; // ok. matches "a*" and "*"
|
||||
| ^
|
||||
|
||||
error: aborting due to 12 previous errors
|
||||
|
||||
|
@ -12,6 +12,8 @@ LL | macro_rules! foo {
|
||||
...
|
||||
LL | foo!(a?);
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
||||
= note: while trying to match sequence end
|
||||
|
||||
error: no rules expected the token `?`
|
||||
--> $DIR/macro-at-most-once-rep-2018.rs:26:11
|
||||
@ -21,6 +23,8 @@ LL | macro_rules! foo {
|
||||
...
|
||||
LL | foo!(a?a);
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
||||
= note: while trying to match sequence end
|
||||
|
||||
error: no rules expected the token `?`
|
||||
--> $DIR/macro-at-most-once-rep-2018.rs:27:11
|
||||
@ -30,6 +34,8 @@ LL | macro_rules! foo {
|
||||
...
|
||||
LL | foo!(a?a?a);
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
||||
= note: while trying to match sequence end
|
||||
|
||||
error: unexpected end of macro invocation
|
||||
--> $DIR/macro-at-most-once-rep-2018.rs:29:5
|
||||
@ -39,6 +45,12 @@ LL | macro_rules! barplus {
|
||||
...
|
||||
LL | barplus!();
|
||||
| ^^^^^^^^^^ missing tokens in macro arguments
|
||||
|
|
||||
note: while trying to match `+`
|
||||
--> $DIR/macro-at-most-once-rep-2018.rs:15:11
|
||||
|
|
||||
LL | ($(a)?+) => {}; // ok. matches "a+" and "+"
|
||||
| ^
|
||||
|
||||
error: unexpected end of macro invocation
|
||||
--> $DIR/macro-at-most-once-rep-2018.rs:30:15
|
||||
@ -48,6 +60,12 @@ LL | macro_rules! barplus {
|
||||
...
|
||||
LL | barplus!(a);
|
||||
| ^ missing tokens in macro arguments
|
||||
|
|
||||
note: while trying to match `+`
|
||||
--> $DIR/macro-at-most-once-rep-2018.rs:15:11
|
||||
|
|
||||
LL | ($(a)?+) => {}; // ok. matches "a+" and "+"
|
||||
| ^
|
||||
|
||||
error: no rules expected the token `?`
|
||||
--> $DIR/macro-at-most-once-rep-2018.rs:31:15
|
||||
@ -57,6 +75,12 @@ LL | macro_rules! barplus {
|
||||
...
|
||||
LL | barplus!(a?);
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match `+`
|
||||
--> $DIR/macro-at-most-once-rep-2018.rs:15:11
|
||||
|
|
||||
LL | ($(a)?+) => {}; // ok. matches "a+" and "+"
|
||||
| ^
|
||||
|
||||
error: no rules expected the token `?`
|
||||
--> $DIR/macro-at-most-once-rep-2018.rs:32:15
|
||||
@ -66,6 +90,12 @@ LL | macro_rules! barplus {
|
||||
...
|
||||
LL | barplus!(a?a);
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match `+`
|
||||
--> $DIR/macro-at-most-once-rep-2018.rs:15:11
|
||||
|
|
||||
LL | ($(a)?+) => {}; // ok. matches "a+" and "+"
|
||||
| ^
|
||||
|
||||
error: unexpected end of macro invocation
|
||||
--> $DIR/macro-at-most-once-rep-2018.rs:36:5
|
||||
@ -75,6 +105,12 @@ LL | macro_rules! barstar {
|
||||
...
|
||||
LL | barstar!();
|
||||
| ^^^^^^^^^^ missing tokens in macro arguments
|
||||
|
|
||||
note: while trying to match `*`
|
||||
--> $DIR/macro-at-most-once-rep-2018.rs:19:11
|
||||
|
|
||||
LL | ($(a)?*) => {}; // ok. matches "a*" and "*"
|
||||
| ^
|
||||
|
||||
error: unexpected end of macro invocation
|
||||
--> $DIR/macro-at-most-once-rep-2018.rs:37:15
|
||||
@ -84,6 +120,12 @@ LL | macro_rules! barstar {
|
||||
...
|
||||
LL | barstar!(a);
|
||||
| ^ missing tokens in macro arguments
|
||||
|
|
||||
note: while trying to match `*`
|
||||
--> $DIR/macro-at-most-once-rep-2018.rs:19:11
|
||||
|
|
||||
LL | ($(a)?*) => {}; // ok. matches "a*" and "*"
|
||||
| ^
|
||||
|
||||
error: no rules expected the token `?`
|
||||
--> $DIR/macro-at-most-once-rep-2018.rs:38:15
|
||||
@ -93,6 +135,12 @@ LL | macro_rules! barstar {
|
||||
...
|
||||
LL | barstar!(a?);
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match `*`
|
||||
--> $DIR/macro-at-most-once-rep-2018.rs:19:11
|
||||
|
|
||||
LL | ($(a)?*) => {}; // ok. matches "a*" and "*"
|
||||
| ^
|
||||
|
||||
error: no rules expected the token `?`
|
||||
--> $DIR/macro-at-most-once-rep-2018.rs:39:15
|
||||
@ -102,6 +150,12 @@ LL | macro_rules! barstar {
|
||||
...
|
||||
LL | barstar!(a?a);
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match `*`
|
||||
--> $DIR/macro-at-most-once-rep-2018.rs:19:11
|
||||
|
|
||||
LL | ($(a)?*) => {}; // ok. matches "a*" and "*"
|
||||
| ^
|
||||
|
||||
error: aborting due to 12 previous errors
|
||||
|
||||
|
@ -6,6 +6,12 @@ LL | macro_rules! m { ($x:lifetime) => { } }
|
||||
...
|
||||
LL | m!(a);
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match meta-variable `$x:lifetime`
|
||||
--> $DIR/macro-non-lifetime.rs:3:19
|
||||
|
|
||||
LL | macro_rules! m { ($x:lifetime) => { } }
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -14,6 +14,12 @@ LL | foo!(a b);
|
||||
| -^ no rules expected this token in macro call
|
||||
| |
|
||||
| help: missing comma here
|
||||
|
|
||||
note: while trying to match meta-variable `$a:ident`
|
||||
--> $DIR/missing-comma.rs:2:6
|
||||
|
|
||||
LL | ($a:ident) => ();
|
||||
| ^^^^^^^^
|
||||
|
||||
error: no rules expected the token `e`
|
||||
--> $DIR/missing-comma.rs:23:21
|
||||
@ -25,6 +31,12 @@ LL | foo!(a, b, c, d e);
|
||||
| -^ no rules expected this token in macro call
|
||||
| |
|
||||
| help: missing comma here
|
||||
|
|
||||
note: while trying to match meta-variable `$d:ident`
|
||||
--> $DIR/missing-comma.rs:5:36
|
||||
|
|
||||
LL | ($a:ident, $b:ident, $c:ident, $d:ident) => ();
|
||||
| ^^^^^^^^
|
||||
|
||||
error: no rules expected the token `d`
|
||||
--> $DIR/missing-comma.rs:25:18
|
||||
@ -36,6 +48,12 @@ LL | foo!(a, b, c d, e);
|
||||
| -^ no rules expected this token in macro call
|
||||
| |
|
||||
| help: missing comma here
|
||||
|
|
||||
note: while trying to match meta-variable `$c:ident`
|
||||
--> $DIR/missing-comma.rs:4:26
|
||||
|
|
||||
LL | ($a:ident, $b:ident, $c:ident) => ();
|
||||
| ^^^^^^^^
|
||||
|
||||
error: no rules expected the token `d`
|
||||
--> $DIR/missing-comma.rs:27:18
|
||||
@ -45,6 +63,12 @@ LL | macro_rules! foo {
|
||||
...
|
||||
LL | foo!(a, b, c d e);
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match meta-variable `$c:ident`
|
||||
--> $DIR/missing-comma.rs:4:26
|
||||
|
|
||||
LL | ($a:ident, $b:ident, $c:ident) => ();
|
||||
| ^^^^^^^^
|
||||
|
||||
error: unexpected end of macro invocation
|
||||
--> $DIR/missing-comma.rs:29:23
|
||||
@ -54,6 +78,12 @@ LL | macro_rules! bar {
|
||||
...
|
||||
LL | bar!(Level::Error, );
|
||||
| ^ missing tokens in macro arguments
|
||||
|
|
||||
note: while trying to match meta-variable `$arg:tt`
|
||||
--> $DIR/missing-comma.rs:10:19
|
||||
|
|
||||
LL | ($lvl:expr, $($arg:tt)+) => {}
|
||||
| ^^^^^^^
|
||||
|
||||
error: no rules expected the token `,`
|
||||
--> $DIR/missing-comma.rs:32:38
|
||||
@ -63,6 +93,12 @@ LL | macro_rules! check {
|
||||
...
|
||||
LL | check!(<str as Debug>::fmt, "fmt",);
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match meta-variable `$expected:expr`
|
||||
--> $DIR/missing-comma.rs:14:14
|
||||
|
|
||||
LL | ($ty:ty, $expected:expr) => {};
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
|
@ -10,6 +10,14 @@ LL | n!(a $nt_item b);
|
||||
LL | complex_nonterminal!(enum E {});
|
||||
| ------------------------------- in this macro invocation
|
||||
|
|
||||
note: while trying to match `enum E {}`
|
||||
--> $DIR/nonterminal-matching.rs:15:15
|
||||
|
|
||||
LL | macro n(a $nt_item b) {
|
||||
| ^^^^^^^^
|
||||
...
|
||||
LL | complex_nonterminal!(enum E {});
|
||||
| ------------------------------- in this macro invocation
|
||||
= note: this error originates in the macro `complex_nonterminal` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -10,6 +10,7 @@ LL | my_faulty_macro!(bcd);
|
||||
LL | my_faulty_macro!();
|
||||
| ------------------ in this macro invocation
|
||||
|
|
||||
= note: while trying to match end of macro
|
||||
= note: this error originates in the macro `my_faulty_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
note: trace_macro
|
||||
|
8
src/test/ui/on-unimplemented/issue-104140.rs
Normal file
8
src/test/ui/on-unimplemented/issue-104140.rs
Normal file
@ -0,0 +1,8 @@
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
trait Foo {}
|
||||
|
||||
#[rustc_on_unimplemented] //~ ERROR malformed `rustc_on_unimplemented` attribute input
|
||||
impl Foo for u32 {}
|
||||
|
||||
fn main() {}
|
15
src/test/ui/on-unimplemented/issue-104140.stderr
Normal file
15
src/test/ui/on-unimplemented/issue-104140.stderr
Normal file
@ -0,0 +1,15 @@
|
||||
error: malformed `rustc_on_unimplemented` attribute input
|
||||
--> $DIR/issue-104140.rs:5:1
|
||||
|
|
||||
LL | #[rustc_on_unimplemented]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: the following are the possible correct uses
|
||||
|
|
||||
LL | #[rustc_on_unimplemented = "message"]
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
LL | #[rustc_on_unimplemented(/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...")]
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -6,6 +6,12 @@ LL | macro_rules! accept_pat {
|
||||
...
|
||||
LL | accept_pat!(p | q);
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match meta-variable `$p:pat`
|
||||
--> $DIR/or-patterns-syntactic-fail-2018.rs:9:6
|
||||
|
|
||||
LL | ($p:pat) => {};
|
||||
| ^^^^^^
|
||||
|
||||
error: no rules expected the token `|`
|
||||
--> $DIR/or-patterns-syntactic-fail-2018.rs:13:13
|
||||
@ -15,6 +21,12 @@ LL | macro_rules! accept_pat {
|
||||
...
|
||||
LL | accept_pat!(|p| q);
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match meta-variable `$p:pat`
|
||||
--> $DIR/or-patterns-syntactic-fail-2018.rs:9:6
|
||||
|
|
||||
LL | ($p:pat) => {};
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
26
src/test/ui/parser/issues/issue-104088.rs
Normal file
26
src/test/ui/parser/issues/issue-104088.rs
Normal file
@ -0,0 +1,26 @@
|
||||
fn test() {
|
||||
if let 123 = 123 { println!("yes"); }
|
||||
}
|
||||
|
||||
fn test_2() {
|
||||
let 1x = 123;
|
||||
//~^ ERROR expected identifier, found number literal
|
||||
}
|
||||
|
||||
fn test_3() {
|
||||
let 2x: i32 = 123;
|
||||
//~^ ERROR expected identifier, found number literal
|
||||
}
|
||||
|
||||
fn test_4() {
|
||||
if let 2e1 = 123 {
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
}
|
||||
|
||||
fn test_5() {
|
||||
let 23name = 123;
|
||||
//~^ ERROR expected identifier, found number literal
|
||||
}
|
||||
|
||||
fn main() {}
|
29
src/test/ui/parser/issues/issue-104088.stderr
Normal file
29
src/test/ui/parser/issues/issue-104088.stderr
Normal file
@ -0,0 +1,29 @@
|
||||
error: expected identifier, found number literal
|
||||
--> $DIR/issue-104088.rs:6:9
|
||||
|
|
||||
LL | let 1x = 123;
|
||||
| ^^ identifiers cannot start with a number
|
||||
|
||||
error: expected identifier, found number literal
|
||||
--> $DIR/issue-104088.rs:11:9
|
||||
|
|
||||
LL | let 2x: i32 = 123;
|
||||
| ^^ identifiers cannot start with a number
|
||||
|
||||
error: expected identifier, found number literal
|
||||
--> $DIR/issue-104088.rs:22:9
|
||||
|
|
||||
LL | let 23name = 123;
|
||||
| ^^^^^^ identifiers cannot start with a number
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-104088.rs:16:12
|
||||
|
|
||||
LL | if let 2e1 = 123 {
|
||||
| ^^^ --- this expression has type `{integer}`
|
||||
| |
|
||||
| expected integer, found floating-point number
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -9,6 +9,12 @@ LL | //! Inner
|
||||
| |
|
||||
| no rules expected this token in macro call
|
||||
| inner doc comments expand to `#![doc = "..."]`, which is what this macro attempted to match
|
||||
|
|
||||
note: while trying to match `[`
|
||||
--> $DIR/macro-doc-comments-1.rs:2:7
|
||||
|
|
||||
LL | (#[$outer:meta]) => ()
|
||||
| ^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -9,6 +9,12 @@ LL | /// Outer
|
||||
| |
|
||||
| no rules expected this token in macro call
|
||||
| outer doc comments expand to `#[doc = "..."]`, which is what this macro attempted to match
|
||||
|
|
||||
note: while trying to match `!`
|
||||
--> $DIR/macro-doc-comments-2.rs:2:7
|
||||
|
|
||||
LL | (#![$inner:meta]) => ()
|
||||
| ^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -72,6 +72,12 @@ LL | macro_rules! use_expr {
|
||||
...
|
||||
LL | use_expr!(let 0 = 1);
|
||||
| ^^^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match meta-variable `$e:expr`
|
||||
--> $DIR/feature-gate.rs:61:10
|
||||
|
|
||||
LL | ($e:expr) => {
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0658]: `if let` guards are experimental
|
||||
--> $DIR/feature-gate.rs:7:12
|
||||
|
@ -18,6 +18,12 @@ LL | macro_rules! use_expr {
|
||||
...
|
||||
LL | use_expr!(let 0 = 1);
|
||||
| ^^^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match meta-variable `$e:expr`
|
||||
--> $DIR/feature-gate.rs:50:10
|
||||
|
|
||||
LL | ($e:expr) => {
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:14:16
|
||||
|
@ -6,6 +6,12 @@ LL | macro_rules! identity {
|
||||
...
|
||||
LL | let identity!(_) = 10;
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match meta-variable `$i:ident`
|
||||
--> $DIR/underscore-ident-matcher.rs:2:6
|
||||
|
|
||||
LL | ($i: ident) => (
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user