Auto merge of #61649 - Centril:rollup-b4nx9k9, r=Centril

Rollup of 7 pull requests

Successful merges:

 - #61223 (Document tuple's Ord behavior as sequential)
 - #61615 (syntax: Treat error literals in more principled way)
 - #61616 (parser: Remove `Deref` impl from `Parser`)
 - #61621 (Clarify when we run steps with ONLY_HOSTS)
 - #61627 (Add regression test for #61452.)
 - #61641 (Revert "Make LocalAnalizer visitor iterate instead of recurse")
 - #61647 (Use stable wrappers in f32/f64::signum)

Failed merges:

r? @ghost
This commit is contained in:
bors 2019-06-08 01:34:53 +00:00
commit 6312b89fda
31 changed files with 377 additions and 349 deletions

View file

@ -59,7 +59,7 @@ pub trait Step: 'static + Clone + Debug + PartialEq + Eq + Hash {
const DEFAULT: bool = false;
/// Run this rule for all hosts without cross compiling.
/// If true, then this rule should be skipped if --target was specified, but --host was not
const ONLY_HOSTS: bool = false;
/// Primary function to execute this rule. Can call `builder.ensure()`
@ -163,7 +163,7 @@ impl StepDescription {
// Determine the targets participating in this rule.
let targets = if self.only_hosts {
if !builder.config.run_host_only {
if builder.config.skip_only_host_steps {
return; // don't run anything
} else {
&builder.hosts
@ -1338,7 +1338,7 @@ mod __test {
let mut config = Config::default_opts();
// don't save toolstates
config.save_toolstates = None;
config.run_host_only = true;
config.skip_only_host_steps = false;
config.dry_run = true;
// try to avoid spurious failures in dist where we create/delete each others file
let dir = config.out.join("tmp-rustbuild-tests").join(
@ -1583,7 +1583,7 @@ mod __test {
#[test]
fn dist_with_target_flag() {
let mut config = configure(&["B"], &["C"]);
config.run_host_only = false; // as-if --target=C was passed
config.skip_only_host_steps = true; // as-if --target=C was passed
let build = Build::new(config);
let mut builder = Builder::new(&build);
builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]);
@ -1831,7 +1831,7 @@ mod __test {
#[test]
fn build_with_target_flag() {
let mut config = configure(&["B"], &["C"]);
config.run_host_only = false;
config.skip_only_host_steps = true;
let build = Build::new(config);
let mut builder = Builder::new(&build);
builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]);

View file

@ -51,7 +51,7 @@ pub struct Config {
pub test_compare_mode: bool,
pub llvm_libunwind: bool,
pub run_host_only: bool,
pub skip_only_host_steps: bool,
pub on_fail: Option<String>,
pub stage: Option<u32>,
@ -416,7 +416,9 @@ impl Config {
}
// If --target was specified but --host wasn't specified, don't run any host-only tests.
config.run_host_only = !(flags.host.is_empty() && !flags.target.is_empty());
let has_hosts = !flags.host.is_empty();
let has_targets = !flags.target.is_empty();
config.skip_only_host_steps = !has_hosts && has_targets;
let toml = file.map(|file| {
let contents = t!(fs::read_to_string(&file));

View file

@ -1020,7 +1020,6 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
ExprKind::AddrOf(_, ref subexpression) | ExprKind::Unary(_, ref subexpression) => {
visitor.visit_expr(subexpression)
}
ExprKind::Lit(_) => {}
ExprKind::Cast(ref subexpression, ref typ) | ExprKind::Type(ref subexpression, ref typ) => {
visitor.visit_expr(subexpression);
visitor.visit_ty(typ)
@ -1093,7 +1092,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
ExprKind::Yield(ref subexpression) => {
visitor.visit_expr(subexpression);
}
ExprKind::Err => {}
ExprKind::Lit(_) | ExprKind::Err => {}
}
}

View file

@ -170,14 +170,14 @@ impl_stable_hash_for!(struct ::syntax::ast::Lit {
impl_stable_hash_for!(enum ::syntax::ast::LitKind {
Str(value, style),
Err(value),
ByteStr(value),
Byte(value),
Char(value),
Int(value, lit_int_type),
Float(value, float_ty),
FloatUnsuffixed(value),
Bool(value)
Bool(value),
Err(value)
});
impl_stable_hash_for_spanned!(::syntax::ast::LitKind);

View file

@ -154,62 +154,51 @@ impl<'mir, 'a: 'mir, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
context: PlaceContext,
location: Location) {
debug!("visit_place(place={:?}, context={:?})", place, context);
let mut context = context;
let cx = self.fx.cx;
place.iterate(|place_base, place_projections| {
for proj in place_projections {
// Allow uses of projections that are ZSTs or from scalar fields.
let is_consume = match context {
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) |
PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => true,
_ => false
};
if is_consume {
let base_ty = proj.base.ty(self.fx.mir, cx.tcx());
let base_ty = self.fx.monomorphize(&base_ty);
if let mir::Place::Projection(ref proj) = *place {
// Allow uses of projections that are ZSTs or from scalar fields.
let is_consume = match context {
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) |
PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => true,
_ => false
};
if is_consume {
let base_ty = proj.base.ty(self.fx.mir, cx.tcx());
let base_ty = self.fx.monomorphize(&base_ty);
// ZSTs don't require any actual memory access.
let elem_ty = base_ty
.projection_ty(cx.tcx(), &proj.elem)
.ty;
let elem_ty = self.fx.monomorphize(&elem_ty);
if cx.layout_of(elem_ty).is_zst() {
// ZSTs don't require any actual memory access.
let elem_ty = base_ty
.projection_ty(cx.tcx(), &proj.elem)
.ty;
let elem_ty = self.fx.monomorphize(&elem_ty);
if cx.layout_of(elem_ty).is_zst() {
return;
}
if let mir::ProjectionElem::Field(..) = proj.elem {
let layout = cx.layout_of(base_ty.ty);
if cx.is_backend_immediate(layout) || cx.is_backend_scalar_pair(layout) {
// Recurse with the same context, instead of `Projection`,
// potentially stopping at non-operand projections,
// which would trigger `not_ssa` on locals.
self.visit_place(&proj.base, context, location);
return;
}
if let mir::ProjectionElem::Field(..) = proj.elem {
let layout = cx.layout_of(base_ty.ty);
if cx.is_backend_immediate(layout) || cx.is_backend_scalar_pair(layout) {
// Recurse with the same context, instead of `Projection`,
// potentially stopping at non-operand projections,
// which would trigger `not_ssa` on locals.
continue;
}
}
}
// A deref projection only reads the pointer, never needs the place.
if let mir::ProjectionElem::Deref = proj.elem {
return self.visit_place(
&proj.base,
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
location
);
}
context = if context.is_mutating_use() {
PlaceContext::MutatingUse(MutatingUseContext::Projection)
} else {
PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
};
}
// Default base visit behavior
if let mir::PlaceBase::Local(local) = place_base {
self.visit_local(local, context, location);
// A deref projection only reads the pointer, never needs the place.
if let mir::ProjectionElem::Deref = proj.elem {
return self.visit_place(
&proj.base,
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
location
);
}
});
}
self.super_place(place, context, location);
}
fn visit_local(&mut self,

View file

@ -34,15 +34,6 @@ crate fn lit_to_const<'a, 'gcx, 'tcx>(
let allocation = tcx.intern_const_alloc(allocation);
ConstValue::Slice { data: allocation, start: 0, end: s.len() }
},
LitKind::Err(ref s) => {
let s = s.as_str();
let allocation = Allocation::from_byte_aligned_bytes(s.as_bytes());
let allocation = tcx.intern_const_alloc(allocation);
return Ok(tcx.mk_const(ty::Const {
val: ConstValue::Slice{ data: allocation, start: 0, end: s.len() },
ty: tcx.types.err,
}));
},
LitKind::ByteStr(ref data) => {
let id = tcx.allocate_bytes(data);
ConstValue::Scalar(Scalar::Ptr(id.into()))
@ -66,6 +57,7 @@ crate fn lit_to_const<'a, 'gcx, 'tcx>(
}
LitKind::Bool(b) => ConstValue::Scalar(Scalar::from_bool(b)),
LitKind::Char(c) => ConstValue::Scalar(Scalar::from_char(c)),
LitKind::Err(_) => unreachable!(),
};
Ok(tcx.mk_const(ty::Const { val: lit, ty }))
}

View file

@ -188,7 +188,7 @@ impl f32 {
if self.is_nan() {
NAN
} else {
unsafe { intrinsics::copysignf32(1.0, self) }
1.0_f32.copysign(self)
}
}

View file

@ -166,7 +166,7 @@ impl f64 {
if self.is_nan() {
NAN
} else {
unsafe { intrinsics::copysignf64(1.0, self) }
1.0_f64.copysign(self)
}
}

View file

@ -683,6 +683,10 @@ mod prim_str { }
/// assert_eq!(tuple.2, 'c');
/// ```
///
/// The sequential nature of the tuple applies to its implementations of various
/// traits. For example, in `PartialOrd` and `Ord`, the elements are compared
/// sequentially until the first non-equal set is found.
///
/// For more about tuples, see [the book](../book/ch03-02-data-types.html#the-tuple-type).
///
/// # Trait implementations

View file

@ -1368,7 +1368,7 @@ pub enum LitKind {
FloatUnsuffixed(Symbol),
/// A boolean literal.
Bool(bool),
/// A recovered character literal that contains mutliple `char`s, most likely a typo.
/// Placeholder for a literal that wasn't well-formed in some way.
Err(Symbol),
}
@ -1406,10 +1406,10 @@ impl LitKind {
| LitKind::ByteStr(..)
| LitKind::Byte(..)
| LitKind::Char(..)
| LitKind::Err(..)
| LitKind::Int(_, LitIntType::Unsuffixed)
| LitKind::FloatUnsuffixed(..)
| LitKind::Bool(..) => true,
| LitKind::Bool(..)
| LitKind::Err(..) => true,
// suffixed variants
LitKind::Int(_, LitIntType::Signed(..))
| LitKind::Int(_, LitIntType::Unsigned(..))

View file

@ -735,9 +735,9 @@ pub fn inject(mut krate: ast::Crate, parse_sess: &ParseSess, attrs: &[String]) -
raw_attr.clone(),
);
let start_span = parser.span;
let start_span = parser.token.span;
let (path, tokens) = panictry!(parser.parse_meta_item_unrestricted());
let end_span = parser.span;
let end_span = parser.token.span;
if parser.token != token::Eof {
parse_sess.span_diagnostic
.span_err(start_span.to(end_span), "invalid crate attribute");

View file

@ -121,7 +121,7 @@ impl<'a> StripUnconfigured<'a> {
let mut expanded_attrs = Vec::with_capacity(1);
while !parser.check(&token::CloseDelim(token::Paren)) {
let lo = parser.span.lo();
let lo = parser.token.span.lo();
let (path, tokens) = parser.parse_meta_item_unrestricted()?;
expanded_attrs.push((path, tokens, parser.prev_span.with_lo(lo)));
parser.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Paren)])?;

View file

@ -1041,7 +1041,7 @@ impl<'a> Parser<'a> {
let msg = format!("macro expansion ignores token `{}` and any following",
self.this_token_to_string());
// Avoid emitting backtrace info twice.
let def_site_span = self.span.with_ctxt(SyntaxContext::empty());
let def_site_span = self.token.span.with_ctxt(SyntaxContext::empty());
let mut err = self.diagnostic().struct_span_err(def_site_span, &msg);
err.span_label(span, "caused by the macro expansion here");
let msg = format!(

View file

@ -105,7 +105,7 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: &[tokenstrea
while self.p.token != token::Eof {
match panictry!(self.p.parse_item()) {
Some(item) => ret.push(item),
None => self.p.diagnostic().span_fatal(self.p.span,
None => self.p.diagnostic().span_fatal(self.p.token.span,
&format!("expected item, found `{}`",
self.p.this_token_to_string()))
.raise()

View file

@ -675,7 +675,7 @@ pub fn parse(
//
// This MatcherPos instance is allocated on the stack. All others -- and
// there are frequently *no* others! -- are allocated on the heap.
let mut initial = initial_matcher_pos(ms, parser.span);
let mut initial = initial_matcher_pos(ms, parser.token.span);
let mut cur_items = smallvec![MatcherPosHandle::Ref(&mut initial)];
let mut next_items = Vec::new();
@ -721,15 +721,15 @@ pub fn parse(
return nameize(sess, ms, matches);
} else if eof_items.len() > 1 {
return Error(
parser.span,
parser.token.span,
"ambiguity: multiple successful parses".to_string(),
);
} else {
return Failure(
Token::new(token::Eof, if parser.span.is_dummy() {
parser.span
Token::new(token::Eof, if parser.token.span.is_dummy() {
parser.token.span
} else {
sess.source_map().next_point(parser.span)
sess.source_map().next_point(parser.token.span)
}),
"missing tokens in macro arguments",
);
@ -753,7 +753,7 @@ pub fn parse(
.join(" or ");
return Error(
parser.span,
parser.token.span,
format!(
"local ambiguity: multiple parsing options: {}",
match next_items.len() {
@ -927,7 +927,7 @@ fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> Nonterminal {
sym::ty => token::NtTy(panictry!(p.parse_ty())),
// this could be handled like a token, since it is one
sym::ident => if let Some((name, is_raw)) = get_macro_name(&p.token) {
let span = p.span;
let span = p.token.span;
p.bump();
token::NtIdent(Ident::new(name, span), is_raw)
} else {

View file

@ -47,7 +47,7 @@ impl<'a> ParserAnyMacro<'a> {
let fragment = panictry!(parser.parse_ast_fragment(kind, true).map_err(|mut e| {
if parser.token == token::Eof && e.message().ends_with(", found `<eof>`") {
if !e.span.is_dummy() { // early end of macro arm (#52866)
e.replace_span_with(parser.sess.source_map().next_point(parser.span));
e.replace_span_with(parser.sess.source_map().next_point(parser.token.span));
}
let msg = &e.message[0];
e.message[0] = (
@ -63,7 +63,7 @@ impl<'a> ParserAnyMacro<'a> {
if parser.sess.source_map().span_to_filename(arm_span).is_real() {
e.span_label(arm_span, "in this macro arm");
}
} else if !parser.sess.source_map().span_to_filename(parser.span).is_real() {
} else if !parser.sess.source_map().span_to_filename(parser.token.span).is_real() {
e.span_label(site_span, "in this macro invocation");
}
e

View file

@ -1101,7 +1101,6 @@ pub fn noop_visit_expr<T: MutVisitor>(Expr { node, id, span, attrs }: &mut Expr,
vis.visit_expr(rhs);
}
ExprKind::Unary(_unop, ohs) => vis.visit_expr(ohs),
ExprKind::Lit(_lit) => {}
ExprKind::Cast(expr, ty) => {
vis.visit_expr(expr);
vis.visit_ty(ty);
@ -1225,7 +1224,7 @@ pub fn noop_visit_expr<T: MutVisitor>(Expr { node, id, span, attrs }: &mut Expr,
}
ExprKind::Try(expr) => vis.visit_expr(expr),
ExprKind::TryBlock(body) => vis.visit_block(body),
ExprKind::Err => {}
ExprKind::Lit(_) | ExprKind::Err => {}
}
vis.visit_id(id);
vis.visit_span(span);

View file

@ -39,7 +39,7 @@ impl<'a> Parser<'a> {
just_parsed_doc_comment = false;
}
token::DocComment(s) => {
let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(), s, self.span);
let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(), s, self.token.span);
if attr.style != ast::AttrStyle::Outer {
let mut err = self.fatal("expected outer doc comment");
err.note("inner doc comments like this (starting with \
@ -83,7 +83,7 @@ impl<'a> Parser<'a> {
self.token);
let (span, path, tokens, style) = match self.token.kind {
token::Pound => {
let lo = self.span;
let lo = self.token.span;
self.bump();
if let InnerAttributeParsePolicy::Permitted = inner_parse_policy {
@ -93,7 +93,7 @@ impl<'a> Parser<'a> {
self.bump();
if let InnerAttributeParsePolicy::NotPermitted { reason } = inner_parse_policy
{
let span = self.span;
let span = self.token.span;
self.diagnostic()
.struct_span_err(span, reason)
.note("inner attributes, like `#![no_std]`, annotate the item \
@ -201,7 +201,7 @@ impl<'a> Parser<'a> {
}
token::DocComment(s) => {
// we need to get the position of this token before we bump.
let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(), s, self.span);
let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(), s, self.token.span);
if attr.style == ast::AttrStyle::Inner {
attrs.push(attr);
self.bump();
@ -249,7 +249,7 @@ impl<'a> Parser<'a> {
return Ok(meta);
}
let lo = self.span;
let lo = self.token.span;
let path = self.parse_path(PathStyle::Mod)?;
let node = self.parse_meta_item_kind()?;
let span = lo.to(self.prev_span);
@ -284,7 +284,7 @@ impl<'a> Parser<'a> {
let found = self.this_token_to_string();
let msg = format!("expected unsuffixed literal or identifier, found `{}`", found);
Err(self.diagnostic().struct_span_err(self.span, &msg))
Err(self.diagnostic().struct_span_err(self.token.span, &msg))
}
/// matches meta_seq = ( COMMASEP(meta_item_inner) )

View file

@ -162,7 +162,7 @@ impl RecoverQPath for Expr {
impl<'a> Parser<'a> {
pub fn fatal(&self, m: &str) -> DiagnosticBuilder<'a> {
self.span_fatal(self.span, m)
self.span_fatal(self.token.span, m)
}
pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> {
@ -174,7 +174,7 @@ impl<'a> Parser<'a> {
}
pub fn bug(&self, m: &str) -> ! {
self.sess.span_diagnostic.span_bug(self.span, m)
self.sess.span_diagnostic.span_bug(self.token.span, m)
}
pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, m: &str) {
@ -199,13 +199,13 @@ impl<'a> Parser<'a> {
crate fn expected_ident_found(&self) -> DiagnosticBuilder<'a> {
let mut err = self.struct_span_err(
self.span,
self.token.span,
&format!("expected identifier, found {}", self.this_token_descr()),
);
if let token::Ident(name, false) = self.token.kind {
if Ident::new(name, self.span).is_raw_guess() {
if Ident::new(name, self.token.span).is_raw_guess() {
err.span_suggestion(
self.span,
self.token.span,
"you can escape reserved keywords to use them as identifiers",
format!("r#{}", name),
Applicability::MaybeIncorrect,
@ -213,12 +213,12 @@ impl<'a> Parser<'a> {
}
}
if let Some(token_descr) = self.token_descr() {
err.span_label(self.span, format!("expected identifier, found {}", token_descr));
err.span_label(self.token.span, format!("expected identifier, found {}", token_descr));
} else {
err.span_label(self.span, "expected identifier");
err.span_label(self.token.span, "expected identifier");
if self.token == token::Comma && self.look_ahead(1, |t| t.is_ident()) {
err.span_suggestion(
self.span,
self.token.span,
"remove this comma",
String::new(),
Applicability::MachineApplicable,
@ -277,11 +277,11 @@ impl<'a> Parser<'a> {
(self.sess.source_map().next_point(self.prev_span),
format!("expected {} here", expect)))
};
self.last_unexpected_token_span = Some(self.span);
self.last_unexpected_token_span = Some(self.token.span);
let mut err = self.fatal(&msg_exp);
if self.token.is_ident_named(sym::and) {
err.span_suggestion_short(
self.span,
self.token.span,
"use `&&` instead of `and` for the boolean operator",
"&&".to_string(),
Applicability::MaybeIncorrect,
@ -289,7 +289,7 @@ impl<'a> Parser<'a> {
}
if self.token.is_ident_named(sym::or) {
err.span_suggestion_short(
self.span,
self.token.span,
"use `||` instead of `or` for the boolean operator",
"||".to_string(),
Applicability::MaybeIncorrect,
@ -326,7 +326,7 @@ impl<'a> Parser<'a> {
self.token.is_keyword(kw::While)
);
let cm = self.sess.source_map();
match (cm.lookup_line(self.span.lo()), cm.lookup_line(sp.lo())) {
match (cm.lookup_line(self.token.span.lo()), cm.lookup_line(sp.lo())) {
(Ok(ref a), Ok(ref b)) if a.line != b.line && is_semi_suggestable => {
// The spans are in different lines, expected `;` and found `let` or `return`.
// High likelihood that it is only a missing `;`.
@ -352,16 +352,16 @@ impl<'a> Parser<'a> {
// | -^^^^^ unexpected token
// | |
// | expected one of 8 possible tokens here
err.span_label(self.span, label_exp);
err.span_label(self.token.span, label_exp);
}
_ if self.prev_span == syntax_pos::DUMMY_SP => {
// Account for macro context where the previous span might not be
// available to avoid incorrect output (#54841).
err.span_label(self.span, "unexpected token");
err.span_label(self.token.span, "unexpected token");
}
_ => {
err.span_label(sp, label_exp);
err.span_label(self.span, "unexpected token");
err.span_label(self.token.span, "unexpected token");
}
}
Err(err)
@ -429,7 +429,7 @@ impl<'a> Parser<'a> {
// Keep the span at the start so we can highlight the sequence of `>` characters to be
// removed.
let lo = self.span;
let lo = self.token.span;
// We need to look-ahead to see if we have `>` characters without moving the cursor forward
// (since we might have the field access case and the characters we're eating are
@ -474,7 +474,7 @@ impl<'a> Parser<'a> {
// Eat from where we started until the end token so that parsing can continue
// as if we didn't have those extra angle brackets.
self.eat_to_tokens(&[&end]);
let span = lo.until(self.span);
let span = lo.until(self.token.span);
let plural = number_of_gt > 1 || number_of_shr >= 1;
self.diagnostic()
@ -502,7 +502,7 @@ impl<'a> Parser<'a> {
match lhs.node {
ExprKind::Binary(op, _, _) if op.node.is_comparison() => {
// respan to include both operators
let op_span = op.span.to(self.span);
let op_span = op.span.to(self.token.span);
let mut err = self.diagnostic().struct_span_err(op_span,
"chained comparison operators require parentheses");
if op.node == BinOpKind::Lt &&
@ -734,15 +734,15 @@ impl<'a> Parser<'a> {
let (prev_sp, sp) = match (&self.token.kind, self.subparser_name) {
// Point at the end of the macro call when reaching end of macro arguments.
(token::Eof, Some(_)) => {
let sp = self.sess.source_map().next_point(self.span);
let sp = self.sess.source_map().next_point(self.token.span);
(sp, sp)
}
// We don't want to point at the following span after DUMMY_SP.
// This happens when the parser finds an empty TokenStream.
_ if self.prev_span == DUMMY_SP => (self.span, self.span),
_ if self.prev_span == DUMMY_SP => (self.token.span, self.token.span),
// EOF, don't want to point at the following char, but rather the last token.
(token::Eof, None) => (self.prev_span, self.span),
_ => (self.sess.source_map().next_point(self.prev_span), self.span),
(token::Eof, None) => (self.prev_span, self.token.span),
_ => (self.sess.source_map().next_point(self.prev_span), self.token.span),
};
let msg = format!(
"expected `{}`, found {}",
@ -789,7 +789,7 @@ impl<'a> Parser<'a> {
// interpreting `await { <expr> }?` as `<expr>?.await`.
self.parse_block_expr(
None,
self.span,
self.token.span,
BlockCheckMode::Default,
ThinVec::new(),
)
@ -819,9 +819,9 @@ impl<'a> Parser<'a> {
self.look_ahead(1, |t| t == &token::CloseDelim(token::Paren))
{
// future.await()
let lo = self.span;
let lo = self.token.span;
self.bump(); // (
let sp = lo.to(self.span);
let sp = lo.to(self.token.span);
self.bump(); // )
self.struct_span_err(sp, "incorrect use of `await`")
.span_suggestion(
@ -854,7 +854,7 @@ impl<'a> Parser<'a> {
next_sp: Span,
maybe_path: bool,
) {
err.span_label(self.span, "expecting a type here because of type ascription");
err.span_label(self.token.span, "expecting a type here because of type ascription");
let cm = self.sess.source_map();
let next_pos = cm.lookup_char_pos(next_sp.lo());
let op_pos = cm.lookup_char_pos(cur_op_span.hi());
@ -911,7 +911,7 @@ impl<'a> Parser<'a> {
// we want to use the last closing delim that would apply
for (i, unmatched) in self.unclosed_delims.iter().enumerate().rev() {
if tokens.contains(&token::CloseDelim(unmatched.expected_delim))
&& Some(self.span) > unmatched.unclosed_span
&& Some(self.token.span) > unmatched.unclosed_span
{
pos = Some(i);
}
@ -1070,28 +1070,28 @@ impl<'a> Parser<'a> {
crate fn expected_semi_or_open_brace(&mut self) -> PResult<'a, ast::TraitItem> {
let token_str = self.this_token_descr();
let mut err = self.fatal(&format!("expected `;` or `{{`, found {}", token_str));
err.span_label(self.span, "expected `;` or `{`");
err.span_label(self.token.span, "expected `;` or `{`");
Err(err)
}
crate fn eat_incorrect_doc_comment(&mut self, applied_to: &str) {
if let token::DocComment(_) = self.token.kind {
let mut err = self.diagnostic().struct_span_err(
self.span,
self.token.span,
&format!("documentation comments cannot be applied to {}", applied_to),
);
err.span_label(self.span, "doc comments are not allowed here");
err.span_label(self.token.span, "doc comments are not allowed here");
err.emit();
self.bump();
} else if self.token == token::Pound && self.look_ahead(1, |t| {
*t == token::OpenDelim(token::Bracket)
}) {
let lo = self.span;
let lo = self.token.span;
// Skip every token until next possible arg.
while self.token != token::CloseDelim(token::Bracket) {
self.bump();
}
let sp = lo.to(self.span);
let sp = lo.to(self.token.span);
self.bump();
let mut err = self.diagnostic().struct_span_err(
sp,
@ -1217,16 +1217,16 @@ impl<'a> Parser<'a> {
crate fn expected_expression_found(&self) -> DiagnosticBuilder<'a> {
let (span, msg) = match (&self.token.kind, self.subparser_name) {
(&token::Eof, Some(origin)) => {
let sp = self.sess.source_map().next_point(self.span);
let sp = self.sess.source_map().next_point(self.token.span);
(sp, format!("expected expression, found end of {}", origin))
}
_ => (self.span, format!(
_ => (self.token.span, format!(
"expected expression, found {}",
self.this_token_descr(),
)),
};
let mut err = self.struct_span_err(span, &msg);
let sp = self.sess.source_map().start_point(self.span);
let sp = self.sess.source_map().start_point(self.token.span);
if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&sp) {
self.sess.expr_parentheses_needed(&mut err, *sp, None);
}

View file

@ -271,14 +271,13 @@ impl<'a> Parser<'a> {
let mut recovered = None;
if self.token == token::Dot {
// Attempt to recover `.4` as `0.4`.
recovered = self.look_ahead(1, |t| {
recovered = self.look_ahead(1, |next_token| {
if let token::Literal(token::Lit { kind: token::Integer, symbol, suffix })
= t.kind {
let next_span = self.look_ahead_span(1);
if self.span.hi() == next_span.lo() {
= next_token.kind {
if self.token.span.hi() == next_token.span.lo() {
let s = String::from("0.") + &symbol.as_str();
let kind = TokenKind::lit(token::Float, Symbol::intern(&s), suffix);
return Some(Token::new(kind, self.span.to(next_span)));
return Some(Token::new(kind, self.token.span.to(next_token.span)));
}
}
None
@ -311,7 +310,11 @@ impl<'a> Parser<'a> {
let (lit, span) = (token.expect_lit(), token.span);
self.bump();
err.report(&self.sess.span_diagnostic, lit, span);
let lit = token::Lit::new(token::Err, lit.symbol, lit.suffix);
// Pack possible quotes and prefixes from the original literal into
// the error literal's symbol so they can be pretty-printed faithfully.
let suffixless_lit = token::Lit::new(lit.kind, lit.symbol, None);
let symbol = Symbol::intern(&pprust::literal_to_string(suffixless_lit));
let lit = token::Lit::new(token::Err, symbol, lit.suffix);
Lit::from_lit_token(lit, span).map_err(|_| unreachable!())
}
}

View file

@ -239,8 +239,8 @@ fn maybe_source_file_to_parser(
let (stream, unclosed_delims) = maybe_file_to_stream(sess, source_file, None)?;
let mut parser = stream_to_parser(sess, stream, None);
parser.unclosed_delims = unclosed_delims;
if parser.token == token::Eof && parser.span.is_dummy() {
parser.token.span = Span::new(end_pos, end_pos, parser.span.ctxt());
if parser.token == token::Eof && parser.token.span.is_dummy() {
parser.token.span = Span::new(end_pos, end_pos, parser.token.span.ctxt());
}
Ok(parser)

File diff suppressed because it is too large Load diff

View file

@ -168,9 +168,6 @@ pub fn literal_to_string(lit: token::Lit) -> String {
let mut out = match kind {
token::Byte => format!("b'{}'", symbol),
token::Char => format!("'{}'", symbol),
token::Bool |
token::Float |
token::Integer => symbol.to_string(),
token::Str => format!("\"{}\"", symbol),
token::StrRaw(n) => format!("r{delim}\"{string}\"{delim}",
delim="#".repeat(n as usize),
@ -179,7 +176,10 @@ pub fn literal_to_string(lit: token::Lit) -> String {
token::ByteStrRaw(n) => format!("br{delim}\"{string}\"{delim}",
delim="#".repeat(n as usize),
string=symbol),
token::Err => format!("'{}'", symbol),
token::Integer |
token::Float |
token::Bool |
token::Err => symbol.to_string(),
};
if let Some(suffix) = suffix {

View file

@ -714,7 +714,6 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
ExprKind::AddrOf(_, ref subexpression) | ExprKind::Unary(_, ref subexpression) => {
visitor.visit_expr(subexpression)
}
ExprKind::Lit(_) => {}
ExprKind::Cast(ref subexpression, ref typ) | ExprKind::Type(ref subexpression, ref typ) => {
visitor.visit_expr(subexpression);
visitor.visit_ty(typ)
@ -826,7 +825,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
ExprKind::TryBlock(ref body) => {
visitor.visit_block(body)
}
ExprKind::Err => {}
ExprKind::Lit(_) | ExprKind::Err => {}
}
visitor.visit_expr_post(expression)

View file

@ -85,7 +85,7 @@ fn parse_assert<'a>(
if parser.token == token::Semi {
let mut err = cx.struct_span_warn(sp, "macro requires an expression as an argument");
err.span_suggestion(
parser.span,
parser.token.span,
"try removing semicolon",
String::new(),
Applicability::MaybeIncorrect
@ -105,7 +105,7 @@ fn parse_assert<'a>(
// turned into an error.
let custom_message = if let token::Literal(token::Lit { kind: token::Str, .. })
= parser.token.kind {
let mut err = cx.struct_span_warn(parser.span, "unexpected string literal");
let mut err = cx.struct_span_warn(parser.token.span, "unexpected string literal");
let comma_span = cx.source_map().next_point(parser.prev_span);
err.span_suggestion_short(
comma_span,

View file

@ -22,7 +22,6 @@ pub fn expand_syntax_ext(
match e.node {
ast::ExprKind::Lit(ref lit) => match lit.node {
ast::LitKind::Str(ref s, _)
| ast::LitKind::Err(ref s)
| ast::LitKind::Float(ref s, _)
| ast::LitKind::FloatUnsuffixed(ref s) => {
accumulator.push_str(&s.as_str());
@ -41,6 +40,9 @@ pub fn expand_syntax_ext(
ast::LitKind::Byte(..) | ast::LitKind::ByteStr(..) => {
cx.span_err(e.span, "cannot concatenate a byte string literal");
}
ast::LitKind::Err(_) => {
has_errors = true;
}
},
ast::ExprKind::Err => {
has_errors = true;

View file

@ -142,7 +142,7 @@ fn parse_args<'a>(
while p.token != token::Eof {
if !p.eat(&token::Comma) {
return Err(ecx.struct_span_err(p.span, "expected token: `,`"));
return Err(ecx.struct_span_err(p.token.span, "expected token: `,`"));
}
if p.token == token::Eof {
break;
@ -154,7 +154,7 @@ fn parse_args<'a>(
name
} else {
return Err(ecx.struct_span_err(
p.span,
p.token.span,
"expected ident, positional arguments cannot follow named arguments",
));
};

View file

@ -0,0 +1,14 @@
// edition:2018
#![feature(async_await)]
pub async fn f(x: Option<usize>) {
x.take();
//~^ ERROR cannot borrow `x` as mutable, as it is not declared as mutable [E0596]
}
pub async fn g(x: usize) {
x += 1;
//~^ ERROR cannot assign twice to immutable variable `x` [E0384]
}
fn main() {}

View file

@ -0,0 +1,23 @@
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/issue-61452.rs:5:5
|
LL | pub async fn f(x: Option<usize>) {
| - help: consider changing this to be mutable: `mut x`
LL | x.take();
| ^ cannot borrow as mutable
error[E0384]: cannot assign twice to immutable variable `x`
--> $DIR/issue-61452.rs:10:5
|
LL | pub async fn g(x: usize) {
| -
| |
| first assignment to `x`
| help: make this binding mutable: `mut x`
LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0384, E0596.
For more information about an error, try `rustc --explain E0384`.

View file

@ -12,4 +12,9 @@ mod nonexistent_env {
//~^ ERROR environment variable `NON_EXISTENT` not defined
}
mod erroneous_literal {
include!(concat!("NON_EXISTENT"suffix, "/data.rs"));
//~^ ERROR suffixes on a string literal are invalid
}
fn main() {}

View file

@ -4,6 +4,12 @@ error: environment variable `NON_EXISTENT` not defined
LL | include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
| ^^^^^^^^^^^^^^^^^^^^
error: suffixes on a string literal are invalid
--> $DIR/issue-55897.rs:16:22
|
LL | include!(concat!("NON_EXISTENT"suffix, "/data.rs"));
| ^^^^^^^^^^^^^^^^^^^^ invalid suffix `suffix`
error[E0432]: unresolved import `prelude`
--> $DIR/issue-55897.rs:1:5
|
@ -21,6 +27,6 @@ LL | include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
|
= note: import resolution is stuck, try simplifying macro imports
error: aborting due to 3 previous errors
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0432`.