1
Fork 0

Auto merge of #107408 - matthiaskrgr:rollup-b5vz2ow, r=matthiaskrgr

Rollup of 9 pull requests

Successful merges:

 - #104012 (Improve unexpected close and mismatch delimiter hint in TokenTreesReader)
 - #104252 (Stabilize the const_socketaddr feature)
 - #105524 (Replace libc::{type} with crate::ffi::{type})
 - #107096 (Detect references to non-existant messages in Fluent resources)
 - #107355 (Add regression test for #60755)
 - #107384 (Remove `BOOL_TY_FOR_UNIT_TESTING`)
 - #107385 (Use `FallibleTypeFolder` for `ConstInferUnifier` not `TypeRelation`)
 - #107391 (rustdoc: remove inline javascript from copy-path button)
 - #107398 (Remove `ControlFlow::{BREAK, CONTINUE}`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2023-01-28 13:12:59 +00:00
commit bca8b4dc32
57 changed files with 557 additions and 312 deletions

View file

@ -23,7 +23,7 @@ codegen_gcc_invalid_monomorphization_unsupported_element =
invalid monomorphization of `{$name}` intrinsic: unsupported {$name} from `{$in_ty}` with element `{$elem_ty}` to `{$ret_ty}`
codegen_gcc_invalid_monomorphization_invalid_bitmask =
invalid monomorphization of `{$name}` intrinsic: invalid bitmask `{ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]`
invalid monomorphization of `{$name}` intrinsic: invalid bitmask `{$ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]`
codegen_gcc_invalid_monomorphization_simd_shuffle =
invalid monomorphization of `{$name}` intrinsic: simd_shuffle index must be an array of `u32`, got `{$ty}`

View file

@ -179,9 +179,9 @@ codegen_ssa_extract_bundled_libs_write_file = failed to write file '{$rlib}': {$
codegen_ssa_unsupported_arch = unsupported arch `{$arch}` for os `{$os}`
codegen_ssa_apple_sdk_error_sdk_path = failed to get {$sdk_name} SDK path: {error}
codegen_ssa_apple_sdk_error_sdk_path = failed to get {$sdk_name} SDK path: {$error}
codegen_ssa_read_file = failed to read file: {message}
codegen_ssa_read_file = failed to read file: {$message}
codegen_ssa_unsupported_link_self_contained = option `-C link-self-contained` is not supported on this target

View file

@ -37,7 +37,10 @@ use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, InferConst, Ty, TyCtxt, TypeVisitable};
use rustc_middle::ty::{
self, FallibleTypeFolder, InferConst, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable,
TypeVisitable,
};
use rustc_middle::ty::{IntType, UintType};
use rustc_span::{Span, DUMMY_SP};
@ -140,8 +143,6 @@ impl<'tcx> InferCtxt<'tcx> {
let a = self.shallow_resolve(a);
let b = self.shallow_resolve(b);
let a_is_expected = relation.a_is_expected();
match (a.kind(), b.kind()) {
(
ty::ConstKind::Infer(InferConst::Var(a_vid)),
@ -158,11 +159,11 @@ impl<'tcx> InferCtxt<'tcx> {
}
(ty::ConstKind::Infer(InferConst::Var(vid)), _) => {
return self.unify_const_variable(relation.param_env(), vid, b, a_is_expected);
return self.unify_const_variable(vid, b);
}
(_, ty::ConstKind::Infer(InferConst::Var(vid))) => {
return self.unify_const_variable(relation.param_env(), vid, a, !a_is_expected);
return self.unify_const_variable(vid, a);
}
(ty::ConstKind::Unevaluated(..), _) if self.tcx.lazy_normalization() => {
// FIXME(#59490): Need to remove the leak check to accommodate
@ -223,10 +224,8 @@ impl<'tcx> InferCtxt<'tcx> {
#[instrument(level = "debug", skip(self))]
fn unify_const_variable(
&self,
param_env: ty::ParamEnv<'tcx>,
target_vid: ty::ConstVid<'tcx>,
ct: ty::Const<'tcx>,
vid_is_expected: bool,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
let (for_universe, span) = {
let mut inner = self.inner.borrow_mut();
@ -239,8 +238,12 @@ impl<'tcx> InferCtxt<'tcx> {
ConstVariableValue::Unknown { universe } => (universe, var_value.origin.span),
}
};
let value = ConstInferUnifier { infcx: self, span, param_env, for_universe, target_vid }
.relate(ct, ct)?;
let value = ct.try_fold_with(&mut ConstInferUnifier {
infcx: self,
span,
for_universe,
target_vid,
})?;
self.inner.borrow_mut().const_unification_table().union_value(
target_vid,
@ -800,8 +803,6 @@ struct ConstInferUnifier<'cx, 'tcx> {
span: Span,
param_env: ty::ParamEnv<'tcx>,
for_universe: ty::UniverseIndex,
/// The vid of the const variable that is in the process of being
@ -810,61 +811,15 @@ struct ConstInferUnifier<'cx, 'tcx> {
target_vid: ty::ConstVid<'tcx>,
}
// We use `TypeRelation` here to propagate `RelateResult` upwards.
//
// Both inputs are expected to be the same.
impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
fn tcx(&self) -> TyCtxt<'tcx> {
impl<'tcx> FallibleTypeFolder<'tcx> for ConstInferUnifier<'_, 'tcx> {
type Error = TypeError<'tcx>;
fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
self.infcx.tcx
}
fn intercrate(&self) -> bool {
assert!(!self.infcx.intercrate);
false
}
fn param_env(&self) -> ty::ParamEnv<'tcx> {
self.param_env
}
fn tag(&self) -> &'static str {
"ConstInferUnifier"
}
fn a_is_expected(&self) -> bool {
true
}
fn mark_ambiguous(&mut self) {
bug!()
}
fn relate_with_variance<T: Relate<'tcx>>(
&mut self,
_variance: ty::Variance,
_info: ty::VarianceDiagInfo<'tcx>,
a: T,
b: T,
) -> RelateResult<'tcx, T> {
// We don't care about variance here.
self.relate(a, b)
}
fn binders<T>(
&mut self,
a: ty::Binder<'tcx, T>,
b: ty::Binder<'tcx, T>,
) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
where
T: Relate<'tcx>,
{
Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?))
}
#[instrument(level = "debug", skip(self), ret)]
fn tys(&mut self, t: Ty<'tcx>, _t: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
debug_assert_eq!(t, _t);
fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, TypeError<'tcx>> {
match t.kind() {
&ty::Infer(ty::TyVar(vid)) => {
let vid = self.infcx.inner.borrow_mut().type_variables().root_var(vid);
@ -872,7 +827,7 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
match probe {
TypeVariableValue::Known { value: u } => {
debug!("ConstOccursChecker: known value {:?}", u);
self.tys(u, u)
u.try_fold_with(self)
}
TypeVariableValue::Unknown { universe } => {
if self.for_universe.can_name(universe) {
@ -892,16 +847,15 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
}
}
ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) => Ok(t),
_ => relate::super_relate_tys(self, t, t),
_ => t.try_super_fold_with(self),
}
}
fn regions(
#[instrument(level = "debug", skip(self), ret)]
fn try_fold_region(
&mut self,
r: ty::Region<'tcx>,
_r: ty::Region<'tcx>,
) -> RelateResult<'tcx, ty::Region<'tcx>> {
debug_assert_eq!(r, _r);
) -> Result<ty::Region<'tcx>, TypeError<'tcx>> {
debug!("ConstInferUnifier: r={:?}", r);
match *r {
@ -930,14 +884,8 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
}
}
#[instrument(level = "debug", skip(self))]
fn consts(
&mut self,
c: ty::Const<'tcx>,
_c: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
debug_assert_eq!(c, _c);
#[instrument(level = "debug", skip(self), ret)]
fn try_fold_const(&mut self, c: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, TypeError<'tcx>> {
match c.kind() {
ty::ConstKind::Infer(InferConst::Var(vid)) => {
// Check if the current unification would end up
@ -958,7 +906,7 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
let var_value =
self.infcx.inner.borrow_mut().const_unification_table().probe_value(vid);
match var_value.val {
ConstVariableValue::Known { value: u } => self.consts(u, u),
ConstVariableValue::Known { value: u } => u.try_fold_with(self),
ConstVariableValue::Unknown { universe } => {
if self.for_universe.can_name(universe) {
Ok(c)
@ -977,17 +925,7 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
}
}
}
ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs }) => {
let substs = self.relate_with_variance(
ty::Variance::Invariant,
ty::VarianceDiagInfo::default(),
substs,
substs,
)?;
Ok(self.tcx().mk_const(ty::UnevaluatedConst { def, substs }, c.ty()))
}
_ => relate::super_relate_consts(self, c, c),
_ => c.try_super_fold_with(self),
}
}
}

View file

@ -4,7 +4,10 @@ use annotate_snippets::{
};
use fluent_bundle::{FluentBundle, FluentError, FluentResource};
use fluent_syntax::{
ast::{Attribute, Entry, Identifier, Message},
ast::{
Attribute, Entry, Expression, Identifier, InlineExpression, Message, Pattern,
PatternElement,
},
parser::ParserError,
};
use proc_macro::{Diagnostic, Level, Span};
@ -185,9 +188,12 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
};
let mut constants = TokenStream::new();
let mut messagerefs = Vec::new();
for entry in resource.entries() {
let span = res.krate.span();
if let Entry::Message(Message { id: Identifier { name }, attributes, .. }) = entry {
if let Entry::Message(Message { id: Identifier { name }, attributes, value, .. }) =
entry
{
let _ = previous_defns.entry(name.to_string()).or_insert(path_span);
if name.contains('-') {
@ -200,6 +206,18 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
.emit();
}
if let Some(Pattern { elements }) = value {
for elt in elements {
if let PatternElement::Placeable {
expression:
Expression::Inline(InlineExpression::MessageReference { id, .. }),
} = elt
{
messagerefs.push((id.name, *name));
}
}
}
// Require that the message name starts with the crate name
// `hir_typeck_foo_bar` (in `hir_typeck.ftl`)
// `const_eval_baz` (in `const_eval.ftl`)
@ -258,6 +276,18 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
}
}
for (mref, name) in messagerefs.into_iter() {
if !previous_defns.contains_key(mref) {
Diagnostic::spanned(
path_span,
Level::Error,
format!("referenced message `{mref}` does not exist (in message `{name}`)"),
)
.help(&format!("you may have meant to use a variable reference (`{{${mref}}}`)"))
.emit();
}
}
if let Err(errs) = bundle.add_resource(resource) {
for e in errs {
match e {

View file

@ -31,7 +31,6 @@ pub use generics::*;
use rustc_ast as ast;
use rustc_ast::node_id::NodeMap;
use rustc_attr as attr;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
use rustc_data_structures::intern::Interned;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@ -453,18 +452,6 @@ pub struct CReaderCacheKey {
#[rustc_pass_by_value]
pub struct Ty<'tcx>(Interned<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>);
impl<'tcx> TyCtxt<'tcx> {
/// A "bool" type used in rustc_mir_transform unit tests when we
/// have not spun up a TyCtxt.
pub const BOOL_TY_FOR_UNIT_TESTING: Ty<'tcx> =
Ty(Interned::new_unchecked(&WithCachedTypeInfo {
internee: ty::Bool,
stable_hash: Fingerprint::ZERO,
flags: TypeFlags::empty(),
outer_exclusive_binder: DebruijnIndex::from_usize(0),
}));
}
impl ty::EarlyBoundRegion {
/// Does this early bound region have a name? Early bound regions normally
/// always have names except when using anonymous lifetimes (`'_`).

View file

@ -0,0 +1,119 @@
use super::UnmatchedBrace;
use rustc_ast::token::Delimiter;
use rustc_errors::Diagnostic;
use rustc_span::source_map::SourceMap;
use rustc_span::Span;
#[derive(Default)]
pub struct TokenTreeDiagInfo {
/// Stack of open delimiters and their spans. Used for error message.
pub open_braces: Vec<(Delimiter, Span)>,
pub unmatched_braces: Vec<UnmatchedBrace>,
/// Used only for error recovery when arriving to EOF with mismatched braces.
pub last_unclosed_found_span: Option<Span>,
/// Collect empty block spans that might have been auto-inserted by editors.
pub empty_block_spans: Vec<Span>,
/// Collect the spans of braces (Open, Close). Used only
/// for detecting if blocks are empty and only braces.
pub matching_block_spans: Vec<(Span, Span)>,
}
pub fn same_identation_level(sm: &SourceMap, open_sp: Span, close_sp: Span) -> bool {
match (sm.span_to_margin(open_sp), sm.span_to_margin(close_sp)) {
(Some(open_padding), Some(close_padding)) => open_padding == close_padding,
_ => false,
}
}
// When we get a `)` or `]` for `{`, we should emit help message here
// it's more friendly compared to report `unmatched error` in later phase
pub fn report_missing_open_delim(
err: &mut Diagnostic,
unmatched_braces: &[UnmatchedBrace],
) -> bool {
let mut reported_missing_open = false;
for unmatch_brace in unmatched_braces.iter() {
if let Some(delim) = unmatch_brace.found_delim
&& matches!(delim, Delimiter::Parenthesis | Delimiter::Bracket)
{
let missed_open = match delim {
Delimiter::Parenthesis => "(",
Delimiter::Bracket => "[",
_ => unreachable!(),
};
err.span_label(
unmatch_brace.found_span.shrink_to_lo(),
format!("missing open `{}` for this delimiter", missed_open),
);
reported_missing_open = true;
}
}
reported_missing_open
}
pub fn report_suspicious_mismatch_block(
err: &mut Diagnostic,
diag_info: &TokenTreeDiagInfo,
sm: &SourceMap,
delim: Delimiter,
) {
if report_missing_open_delim(err, &diag_info.unmatched_braces) {
return;
}
let mut matched_spans: Vec<(Span, bool)> = diag_info
.matching_block_spans
.iter()
.map(|&(open, close)| (open.with_hi(close.lo()), same_identation_level(sm, open, close)))
.collect();
// sort by `lo`, so the large block spans in the front
matched_spans.sort_by(|a, b| a.0.lo().cmp(&b.0.lo()));
// We use larger block whose identation is well to cover those inner mismatched blocks
// O(N^2) here, but we are on error reporting path, so it is fine
for i in 0..matched_spans.len() {
let (block_span, same_ident) = matched_spans[i];
if same_ident {
for j in i + 1..matched_spans.len() {
let (inner_block, inner_same_ident) = matched_spans[j];
if block_span.contains(inner_block) && !inner_same_ident {
matched_spans[j] = (inner_block, true);
}
}
}
}
// Find the inner-most span candidate for final report
let candidate_span =
matched_spans.into_iter().rev().find(|&(_, same_ident)| !same_ident).map(|(span, _)| span);
if let Some(block_span) = candidate_span {
err.span_label(block_span.shrink_to_lo(), "this delimiter might not be properly closed...");
err.span_label(
block_span.shrink_to_hi(),
"...as it matches this but it has different indentation",
);
// If there is a empty block in the mismatched span, note it
if delim == Delimiter::Brace {
for span in diag_info.empty_block_spans.iter() {
if block_span.contains(*span) {
err.span_label(*span, "block is empty, you might have not meant to close it");
break;
}
}
}
} else {
// If there is no suspicious span, give the last properly closed block may help
if let Some(parent) = diag_info.matching_block_spans.last()
&& diag_info.open_braces.last().is_none()
&& diag_info.empty_block_spans.iter().all(|&sp| sp != parent.0.to(parent.1)) {
err.span_label(parent.0, "this opening brace...");
err.span_label(parent.1, "...matches this closing brace");
}
}
}

View file

@ -17,6 +17,7 @@ use rustc_session::parse::ParseSess;
use rustc_span::symbol::{sym, Symbol};
use rustc_span::{edition::Edition, BytePos, Pos, Span};
mod diagnostics;
mod tokentrees;
mod unescape_error_reporting;
mod unicode_chars;

View file

@ -1,29 +1,18 @@
use super::diagnostics::report_suspicious_mismatch_block;
use super::diagnostics::same_identation_level;
use super::diagnostics::TokenTreeDiagInfo;
use super::{StringReader, UnmatchedBrace};
use rustc_ast::token::{self, Delimiter, Token};
use rustc_ast::tokenstream::{DelimSpan, Spacing, TokenStream, TokenTree};
use rustc_ast_pretty::pprust::token_to_string;
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{PErr, PResult};
use rustc_span::Span;
pub(super) struct TokenTreesReader<'a> {
string_reader: StringReader<'a>,
/// The "next" token, which has been obtained from the `StringReader` but
/// not yet handled by the `TokenTreesReader`.
token: Token,
/// Stack of open delimiters and their spans. Used for error message.
open_braces: Vec<(Delimiter, Span)>,
unmatched_braces: Vec<UnmatchedBrace>,
/// The type and spans for all braces
///
/// Used only for error recovery when arriving to EOF with mismatched braces.
matching_delim_spans: Vec<(Delimiter, Span, Span)>,
last_unclosed_found_span: Option<Span>,
/// Collect empty block spans that might have been auto-inserted by editors.
last_delim_empty_block_spans: FxHashMap<Delimiter, Span>,
/// Collect the spans of braces (Open, Close). Used only
/// for detecting if blocks are empty and only braces.
matching_block_spans: Vec<(Span, Span)>,
diag_info: TokenTreeDiagInfo,
}
impl<'a> TokenTreesReader<'a> {
@ -33,15 +22,10 @@ impl<'a> TokenTreesReader<'a> {
let mut tt_reader = TokenTreesReader {
string_reader,
token: Token::dummy(),
open_braces: Vec::new(),
unmatched_braces: Vec::new(),
matching_delim_spans: Vec::new(),
last_unclosed_found_span: None,
last_delim_empty_block_spans: FxHashMap::default(),
matching_block_spans: Vec::new(),
diag_info: TokenTreeDiagInfo::default(),
};
let res = tt_reader.parse_token_trees(/* is_delimited */ false);
(res, tt_reader.unmatched_braces)
(res, tt_reader.diag_info.unmatched_braces)
}
// Parse a stream of tokens into a list of `TokenTree`s.
@ -92,9 +76,9 @@ impl<'a> TokenTreesReader<'a> {
fn eof_err(&mut self) -> PErr<'a> {
let msg = "this file contains an unclosed delimiter";
let mut err = self.string_reader.sess.span_diagnostic.struct_span_err(self.token.span, msg);
for &(_, sp) in &self.open_braces {
for &(_, sp) in &self.diag_info.open_braces {
err.span_label(sp, "unclosed delimiter");
self.unmatched_braces.push(UnmatchedBrace {
self.diag_info.unmatched_braces.push(UnmatchedBrace {
expected_delim: Delimiter::Brace,
found_delim: None,
found_span: self.token.span,
@ -103,23 +87,13 @@ impl<'a> TokenTreesReader<'a> {
});
}
if let Some((delim, _)) = self.open_braces.last() {
if let Some((_, open_sp, close_sp)) =
self.matching_delim_spans.iter().find(|(d, open_sp, close_sp)| {
let sm = self.string_reader.sess.source_map();
if let Some(close_padding) = sm.span_to_margin(*close_sp) {
if let Some(open_padding) = sm.span_to_margin(*open_sp) {
return delim == d && close_padding != open_padding;
}
}
false
})
// these are in reverse order as they get inserted on close, but
{
// we want the last open/first close
err.span_label(*open_sp, "this delimiter might not be properly closed...");
err.span_label(*close_sp, "...as it matches this but it has different indentation");
}
if let Some((delim, _)) = self.diag_info.open_braces.last() {
report_suspicious_mismatch_block(
&mut err,
&self.diag_info,
&self.string_reader.sess.source_map(),
*delim,
)
}
err
}
@ -128,7 +102,7 @@ impl<'a> TokenTreesReader<'a> {
// The span for beginning of the delimited section
let pre_span = self.token.span;
self.open_braces.push((open_delim, self.token.span));
self.diag_info.open_braces.push((open_delim, self.token.span));
// Parse the token trees within the delimiters.
// We stop at any delimiter so we can try to recover if the user
@ -137,35 +111,29 @@ impl<'a> TokenTreesReader<'a> {
// Expand to cover the entire delimited token tree
let delim_span = DelimSpan::from_pair(pre_span, self.token.span);
let sm = self.string_reader.sess.source_map();
match self.token.kind {
// Correct delimiter.
token::CloseDelim(close_delim) if close_delim == open_delim => {
let (open_brace, open_brace_span) = self.open_braces.pop().unwrap();
let (open_brace, open_brace_span) = self.diag_info.open_braces.pop().unwrap();
let close_brace_span = self.token.span;
if tts.is_empty() {
if tts.is_empty() && close_delim == Delimiter::Brace {
let empty_block_span = open_brace_span.to(close_brace_span);
let sm = self.string_reader.sess.source_map();
if !sm.is_multiline(empty_block_span) {
// Only track if the block is in the form of `{}`, otherwise it is
// likely that it was written on purpose.
self.last_delim_empty_block_spans.insert(open_delim, empty_block_span);
self.diag_info.empty_block_spans.push(empty_block_span);
}
}
//only add braces
// only add braces
if let (Delimiter::Brace, Delimiter::Brace) = (open_brace, open_delim) {
self.matching_block_spans.push((open_brace_span, close_brace_span));
// Add all the matching spans, we will sort by span later
self.diag_info.matching_block_spans.push((open_brace_span, close_brace_span));
}
if self.open_braces.is_empty() {
// Clear up these spans to avoid suggesting them as we've found
// properly matched delimiters so far for an entire block.
self.matching_delim_spans.clear();
} else {
self.matching_delim_spans.push((open_brace, open_brace_span, close_brace_span));
}
// Move past the closing delimiter.
self.token = self.string_reader.next_token().0;
}
@ -174,28 +142,25 @@ impl<'a> TokenTreesReader<'a> {
let mut unclosed_delimiter = None;
let mut candidate = None;
if self.last_unclosed_found_span != Some(self.token.span) {
if self.diag_info.last_unclosed_found_span != Some(self.token.span) {
// do not complain about the same unclosed delimiter multiple times
self.last_unclosed_found_span = Some(self.token.span);
self.diag_info.last_unclosed_found_span = Some(self.token.span);
// This is a conservative error: only report the last unclosed
// delimiter. The previous unclosed delimiters could actually be
// closed! The parser just hasn't gotten to them yet.
if let Some(&(_, sp)) = self.open_braces.last() {
if let Some(&(_, sp)) = self.diag_info.open_braces.last() {
unclosed_delimiter = Some(sp);
};
let sm = self.string_reader.sess.source_map();
if let Some(current_padding) = sm.span_to_margin(self.token.span) {
for (brace, brace_span) in &self.open_braces {
if let Some(padding) = sm.span_to_margin(*brace_span) {
// high likelihood of these two corresponding
if current_padding == padding && brace == &close_delim {
candidate = Some(*brace_span);
}
}
for (brace, brace_span) in &self.diag_info.open_braces {
if same_identation_level(&sm, self.token.span, *brace_span)
&& brace == &close_delim
{
// high likelihood of these two corresponding
candidate = Some(*brace_span);
}
}
let (tok, _) = self.open_braces.pop().unwrap();
self.unmatched_braces.push(UnmatchedBrace {
let (tok, _) = self.diag_info.open_braces.pop().unwrap();
self.diag_info.unmatched_braces.push(UnmatchedBrace {
expected_delim: tok,
found_delim: Some(close_delim),
found_span: self.token.span,
@ -203,7 +168,7 @@ impl<'a> TokenTreesReader<'a> {
candidate_span: candidate,
});
} else {
self.open_braces.pop();
self.diag_info.open_braces.pop();
}
// If the incorrect delimiter matches an earlier opening
@ -213,7 +178,7 @@ impl<'a> TokenTreesReader<'a> {
// fn foo() {
// bar(baz(
// } // Incorrect delimiter but matches the earlier `{`
if !self.open_braces.iter().any(|&(b, _)| b == close_delim) {
if !self.diag_info.open_braces.iter().any(|&(b, _)| b == close_delim) {
self.token = self.string_reader.next_token().0;
}
}
@ -236,22 +201,12 @@ impl<'a> TokenTreesReader<'a> {
let mut err =
self.string_reader.sess.span_diagnostic.struct_span_err(self.token.span, &msg);
// Braces are added at the end, so the last element is the biggest block
if let Some(parent) = self.matching_block_spans.last() {
if let Some(span) = self.last_delim_empty_block_spans.remove(&delim) {
// Check if the (empty block) is in the last properly closed block
if (parent.0.to(parent.1)).contains(span) {
err.span_label(span, "block is empty, you might have not meant to close it");
} else {
err.span_label(parent.0, "this opening brace...");
err.span_label(parent.1, "...matches this closing brace");
}
} else {
err.span_label(parent.0, "this opening brace...");
err.span_label(parent.1, "...matches this closing brace");
}
}
report_suspicious_mismatch_block(
&mut err,
&self.diag_info,
&self.string_reader.sess.source_map(),
delim,
);
err.span_label(self.token.span, "unexpected closing delimiter");
err
}

View file

@ -93,24 +93,24 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
if t.needs_infer() {
if ty::Term::from(t) == self.term {
ControlFlow::BREAK
ControlFlow::Break(())
} else {
t.super_visit_with(self)
}
} else {
ControlFlow::CONTINUE
ControlFlow::Continue(())
}
}
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
if c.needs_infer() {
if ty::Term::from(c) == self.term {
ControlFlow::BREAK
ControlFlow::Break(())
} else {
c.super_visit_with(self)
}
} else {
ControlFlow::CONTINUE
ControlFlow::Continue(())
}
}
}

View file

@ -99,7 +99,7 @@ where
) -> impl FnMut((), T) -> ControlFlow<B> + '_ {
move |(), x| match f(x) {
Some(x) => ControlFlow::Break(x),
None => ControlFlow::CONTINUE,
None => ControlFlow::Continue(()),
}
}

View file

@ -539,7 +539,7 @@ where
#[rustc_inherit_overflow_checks]
fn advance<U: Iterator>(n: usize, iter: &mut U) -> ControlFlow<(), usize> {
match iter.advance_by(n) {
Ok(()) => ControlFlow::BREAK,
Ok(()) => ControlFlow::Break(()),
Err(advanced) => ControlFlow::Continue(n - advanced),
}
}
@ -629,7 +629,7 @@ where
#[rustc_inherit_overflow_checks]
fn advance<U: DoubleEndedIterator>(n: usize, iter: &mut U) -> ControlFlow<(), usize> {
match iter.advance_back_by(n) {
Ok(()) => ControlFlow::BREAK,
Ok(()) => ControlFlow::Break(()),
Err(advanced) => ControlFlow::Continue(n - advanced),
}
}

View file

@ -352,7 +352,7 @@ pub trait DoubleEndedIterator: Iterator {
#[inline]
fn check<T>(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut((), T) -> ControlFlow<T> {
move |(), x| {
if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::CONTINUE }
if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::Continue(()) }
}
}

View file

@ -2601,10 +2601,10 @@ pub trait Iterator {
#[inline]
fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<()> {
move |(), x| {
if f(x) { ControlFlow::CONTINUE } else { ControlFlow::BREAK }
if f(x) { ControlFlow::Continue(()) } else { ControlFlow::Break(()) }
}
}
self.try_fold((), check(f)) == ControlFlow::CONTINUE
self.try_fold((), check(f)) == ControlFlow::Continue(())
}
/// Tests if any element of the iterator matches a predicate.
@ -2654,11 +2654,11 @@ pub trait Iterator {
#[inline]
fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<()> {
move |(), x| {
if f(x) { ControlFlow::BREAK } else { ControlFlow::CONTINUE }
if f(x) { ControlFlow::Break(()) } else { ControlFlow::Continue(()) }
}
}
self.try_fold((), check(f)) == ControlFlow::BREAK
self.try_fold((), check(f)) == ControlFlow::Break(())
}
/// Searches for an element of an iterator that satisfies a predicate.
@ -2717,7 +2717,7 @@ pub trait Iterator {
#[inline]
fn check<T>(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut((), T) -> ControlFlow<T> {
move |(), x| {
if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::CONTINUE }
if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::Continue(()) }
}
}
@ -2749,7 +2749,7 @@ pub trait Iterator {
fn check<T, B>(mut f: impl FnMut(T) -> Option<B>) -> impl FnMut((), T) -> ControlFlow<B> {
move |(), x| match f(x) {
Some(x) => ControlFlow::Break(x),
None => ControlFlow::CONTINUE,
None => ControlFlow::Continue(()),
}
}
@ -2812,7 +2812,7 @@ pub trait Iterator {
R: Residual<Option<I>>,
{
move |(), x| match f(&x).branch() {
ControlFlow::Continue(false) => ControlFlow::CONTINUE,
ControlFlow::Continue(false) => ControlFlow::Continue(()),
ControlFlow::Continue(true) => ControlFlow::Break(Try::from_output(Some(x))),
ControlFlow::Break(r) => ControlFlow::Break(FromResidual::from_residual(r)),
}
@ -3491,7 +3491,7 @@ pub trait Iterator {
F: FnMut(X, Y) -> Ordering,
{
move |x, y| match cmp(x, y) {
Ordering::Equal => ControlFlow::CONTINUE,
Ordering::Equal => ControlFlow::Continue(()),
non_eq => ControlFlow::Break(non_eq),
}
}
@ -3567,7 +3567,7 @@ pub trait Iterator {
F: FnMut(X, Y) -> Option<Ordering>,
{
move |x, y| match partial_cmp(x, y) {
Some(Ordering::Equal) => ControlFlow::CONTINUE,
Some(Ordering::Equal) => ControlFlow::Continue(()),
non_eq => ControlFlow::Break(non_eq),
}
}
@ -3625,7 +3625,7 @@ pub trait Iterator {
F: FnMut(X, Y) -> bool,
{
move |x, y| {
if eq(x, y) { ControlFlow::CONTINUE } else { ControlFlow::BREAK }
if eq(x, y) { ControlFlow::Continue(()) } else { ControlFlow::Break(()) }
}
}
@ -3859,7 +3859,7 @@ pub trait Iterator {
/// Compares two iterators element-wise using the given function.
///
/// If `ControlFlow::CONTINUE` is returned from the function, the comparison moves on to the next
/// If `ControlFlow::Continue(())` is returned from the function, the comparison moves on to the next
/// elements of both iterators. Returning `ControlFlow::Break(x)` short-circuits the iteration and
/// returns `ControlFlow::Break(x)`. If one of the iterators runs out of elements,
/// `ControlFlow::Continue(ord)` is returned where `ord` is the result of comparing the lengths of

View file

@ -259,46 +259,3 @@ impl<R: ops::Try> ControlFlow<R, R::Output> {
}
}
}
impl<B> ControlFlow<B, ()> {
/// It's frequently the case that there's no value needed with `Continue`,
/// so this provides a way to avoid typing `(())`, if you prefer it.
///
/// # Examples
///
/// ```
/// #![feature(control_flow_enum)]
/// use std::ops::ControlFlow;
///
/// let mut partial_sum = 0;
/// let last_used = (1..10).chain(20..25).try_for_each(|x| {
/// partial_sum += x;
/// if partial_sum > 100 { ControlFlow::Break(x) }
/// else { ControlFlow::CONTINUE }
/// });
/// assert_eq!(last_used.break_value(), Some(22));
/// ```
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
pub const CONTINUE: Self = ControlFlow::Continue(());
}
impl<C> ControlFlow<(), C> {
/// APIs like `try_for_each` don't need values with `Break`,
/// so this provides a way to avoid typing `(())`, if you prefer it.
///
/// # Examples
///
/// ```
/// #![feature(control_flow_enum)]
/// use std::ops::ControlFlow;
///
/// let mut partial_sum = 0;
/// (1..10).chain(20..25).try_for_each(|x| {
/// if partial_sum > 100 { ControlFlow::BREAK }
/// else { partial_sum += x; ControlFlow::CONTINUE }
/// });
/// assert_eq!(partial_sum, 108);
/// ```
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
pub const BREAK: Self = ControlFlow::Break(());
}

View file

@ -12,6 +12,8 @@ use crate::time::{Duration, Instant};
use rand::RngCore;
#[cfg(target_os = "macos")]
use crate::ffi::{c_char, c_int};
#[cfg(unix)]
use crate::os::unix::fs::symlink as symlink_dir;
#[cfg(unix)]
@ -24,8 +26,6 @@ use crate::os::windows::fs::{symlink_dir, symlink_file};
use crate::sys::fs::symlink_junction;
#[cfg(target_os = "macos")]
use crate::sys::weak::weak;
#[cfg(target_os = "macos")]
use libc::{c_char, c_int};
macro_rules! check {
($e:expr) => {

View file

@ -358,7 +358,6 @@
#![feature(const_ip)]
#![feature(const_ipv4)]
#![feature(const_ipv6)]
#![feature(const_socketaddr)]
#![feature(thread_local_internals)]
//
#![default_lib_allocator]

View file

@ -133,7 +133,7 @@ impl SocketAddr {
/// ```
#[stable(feature = "ip_addr", since = "1.7.0")]
#[must_use]
#[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")]
#[rustc_const_stable(feature = "const_socketaddr", since = "CURRENT_RUSTC_VERSION")]
pub const fn new(ip: IpAddr, port: u16) -> SocketAddr {
match ip {
IpAddr::V4(a) => SocketAddr::V4(SocketAddrV4::new(a, port)),
@ -153,7 +153,7 @@ impl SocketAddr {
/// ```
#[must_use]
#[stable(feature = "ip_addr", since = "1.7.0")]
#[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")]
#[rustc_const_stable(feature = "const_socketaddr", since = "CURRENT_RUSTC_VERSION")]
pub const fn ip(&self) -> IpAddr {
match *self {
SocketAddr::V4(ref a) => IpAddr::V4(*a.ip()),
@ -194,7 +194,7 @@ impl SocketAddr {
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")]
#[rustc_const_stable(feature = "const_socketaddr", since = "CURRENT_RUSTC_VERSION")]
pub const fn port(&self) -> u16 {
match *self {
SocketAddr::V4(ref a) => a.port(),
@ -238,7 +238,7 @@ impl SocketAddr {
/// ```
#[must_use]
#[stable(feature = "sockaddr_checker", since = "1.16.0")]
#[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")]
#[rustc_const_stable(feature = "const_socketaddr", since = "CURRENT_RUSTC_VERSION")]
pub const fn is_ipv4(&self) -> bool {
matches!(*self, SocketAddr::V4(_))
}
@ -260,7 +260,7 @@ impl SocketAddr {
/// ```
#[must_use]
#[stable(feature = "sockaddr_checker", since = "1.16.0")]
#[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")]
#[rustc_const_stable(feature = "const_socketaddr", since = "CURRENT_RUSTC_VERSION")]
pub const fn is_ipv6(&self) -> bool {
matches!(*self, SocketAddr::V6(_))
}
@ -280,7 +280,7 @@ impl SocketAddrV4 {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use]
#[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")]
#[rustc_const_stable(feature = "const_socketaddr", since = "CURRENT_RUSTC_VERSION")]
pub const fn new(ip: Ipv4Addr, port: u16) -> SocketAddrV4 {
SocketAddrV4 { ip, port }
}
@ -297,7 +297,7 @@ impl SocketAddrV4 {
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")]
#[rustc_const_stable(feature = "const_socketaddr", since = "CURRENT_RUSTC_VERSION")]
pub const fn ip(&self) -> &Ipv4Addr {
&self.ip
}
@ -330,7 +330,7 @@ impl SocketAddrV4 {
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")]
#[rustc_const_stable(feature = "const_socketaddr", since = "CURRENT_RUSTC_VERSION")]
pub const fn port(&self) -> u16 {
self.port
}
@ -371,7 +371,7 @@ impl SocketAddrV6 {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use]
#[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")]
#[rustc_const_stable(feature = "const_socketaddr", since = "CURRENT_RUSTC_VERSION")]
pub const fn new(ip: Ipv6Addr, port: u16, flowinfo: u32, scope_id: u32) -> SocketAddrV6 {
SocketAddrV6 { ip, port, flowinfo, scope_id }
}
@ -388,7 +388,7 @@ impl SocketAddrV6 {
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")]
#[rustc_const_stable(feature = "const_socketaddr", since = "CURRENT_RUSTC_VERSION")]
pub const fn ip(&self) -> &Ipv6Addr {
&self.ip
}
@ -421,7 +421,7 @@ impl SocketAddrV6 {
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")]
#[rustc_const_stable(feature = "const_socketaddr", since = "CURRENT_RUSTC_VERSION")]
pub const fn port(&self) -> u16 {
self.port
}
@ -464,7 +464,7 @@ impl SocketAddrV6 {
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")]
#[rustc_const_stable(feature = "const_socketaddr", since = "CURRENT_RUSTC_VERSION")]
pub const fn flowinfo(&self) -> u32 {
self.flowinfo
}
@ -504,7 +504,7 @@ impl SocketAddrV6 {
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")]
#[rustc_const_stable(feature = "const_socketaddr", since = "CURRENT_RUSTC_VERSION")]
pub const fn scope_id(&self) -> u32 {
self.scope_id
}

View file

@ -1,7 +1,7 @@
//! On Emscripten Rust panics are wrapped in C++ exceptions, so we just forward
//! to `__gxx_personality_v0` which is provided by Emscripten.
use libc::c_int;
use crate::ffi::c_int;
use unwind as uw;
// This is required by the compiler to exist (e.g., it's a lang item), but it's

View file

@ -37,7 +37,8 @@
//! and the last personality routine transfers control to the catch block.
use super::dwarf::eh::{self, EHAction, EHContext};
use libc::{c_int, uintptr_t};
use crate::ffi::c_int;
use libc::uintptr_t;
use unwind as uw;
// Register ids were lifted from LLVM's TargetLowering::getExceptionPointerRegister()

View file

@ -221,7 +221,7 @@ impl Parker {
fn keyed_event_handle() -> c::HANDLE {
const INVALID: c::HANDLE = ptr::invalid_mut(!0);
static HANDLE: AtomicPtr<libc::c_void> = AtomicPtr::new(INVALID);
static HANDLE: AtomicPtr<crate::ffi::c_void> = AtomicPtr::new(INVALID);
match HANDLE.load(Relaxed) {
INVALID => {
let mut handle = c::INVALID_HANDLE_VALUE;

View file

@ -14,7 +14,7 @@ use crate::sys::net::{cvt, cvt_gai, cvt_r, init, wrlen_t, Socket};
use crate::sys_common::{AsInner, FromInner, IntoInner};
use crate::time::Duration;
use libc::{c_int, c_void};
use crate::ffi::{c_int, c_void};
cfg_if::cfg_if! {
if #[cfg(any(
@ -47,7 +47,7 @@ cfg_if::cfg_if! {
target_os = "dragonfly", target_os = "freebsd",
target_os = "openbsd", target_os = "netbsd",
target_os = "solaris", target_os = "illumos"))] {
use libc::c_uchar;
use crate::ffi::c_uchar;
type IpV4MultiCastType = c_uchar;
} else {
type IpV4MultiCastType = c_int;
@ -127,8 +127,8 @@ fn to_ipv6mr_interface(value: u32) -> c_int {
}
#[cfg(not(target_os = "android"))]
fn to_ipv6mr_interface(value: u32) -> libc::c_uint {
value as libc::c_uint
fn to_ipv6mr_interface(value: u32) -> crate::ffi::c_uint {
value as crate::ffi::c_uint
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -61,14 +61,14 @@ impl HtmlWithLimit {
/// and returns [`ControlFlow::Break`].
pub(super) fn push(&mut self, text: &str) -> ControlFlow<(), ()> {
if self.len + text.len() > self.limit {
return ControlFlow::BREAK;
return ControlFlow::Break(());
}
self.flush_queue();
write!(self.buf, "{}", Escape(text)).unwrap();
self.len += text.len();
ControlFlow::CONTINUE
ControlFlow::Continue(())
}
/// Open an HTML tag.

View file

@ -83,7 +83,7 @@ fn past_the_limit() {
buf.push("word#")?;
buf.push(&n.to_string())?;
buf.close_tag();
ControlFlow::CONTINUE
ControlFlow::Continue(())
});
buf.close_tag();
assert_eq!(

View file

@ -1188,18 +1188,18 @@ fn markdown_summary_with_limit(
Event::Start(tag) => match tag {
Tag::Emphasis => buf.open_tag("em"),
Tag::Strong => buf.open_tag("strong"),
Tag::CodeBlock(..) => return ControlFlow::BREAK,
Tag::CodeBlock(..) => return ControlFlow::Break(()),
_ => {}
},
Event::End(tag) => match tag {
Tag::Emphasis | Tag::Strong => buf.close_tag(),
Tag::Paragraph | Tag::Heading(..) => return ControlFlow::BREAK,
Tag::Paragraph | Tag::Heading(..) => return ControlFlow::Break(()),
_ => {}
},
Event::HardBreak | Event::SoftBreak => buf.push(" ")?,
_ => {}
};
ControlFlow::CONTINUE
ControlFlow::Continue(())
});
(buf.finish(), stopped_early)

View file

@ -1142,7 +1142,11 @@ function loadCss(cssUrl) {
(function() {
let reset_button_timeout = null;
window.copy_path = but => {
const but = document.getElementById("copy-path");
if (!but) {
return;
}
but.onclick = () => {
const parent = but.parentElement;
const path = [];

View file

@ -6,7 +6,7 @@
<a href="{{component.path|safe}}index.html">{{component.name}}</a>::<wbr>
{%- endfor -%}
<a class="{{item_type}}" href="#">{{name}}</a> {#- -#}
<button id="copy-path" onclick="copy_path(this)" title="Copy item path to clipboard"> {#- -#}
<button id="copy-path" title="Copy item path to clipboard"> {#- -#}
<img src="{{static_root_path|safe}}{{clipboard_svg}}" {# -#}
width="19" height="18" {# -#}
alt="Copy item path"> {#- -#}

View file

@ -6,7 +6,6 @@
#![feature(array_methods)]
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(control_flow_enum)]
#![feature(drain_filter)]
#![feature(is_terminal)]
#![feature(let_chains)]

View file

@ -1,7 +1,6 @@
#![feature(array_windows)]
#![feature(binary_heap_into_iter_sorted)]
#![feature(box_patterns)]
#![feature(control_flow_enum)]
#![feature(drain_filter)]
#![feature(iter_intersperse)]
#![feature(let_chains)]

View file

@ -54,7 +54,7 @@ fn collect_replace_calls<'tcx>(
from_args.push_front(from);
ControlFlow::Continue(())
} else {
ControlFlow::BREAK
ControlFlow::Break(())
}
} else {
ControlFlow::Continue(())

View file

@ -1,6 +1,5 @@
#![feature(array_chunks)]
#![feature(box_patterns)]
#![feature(control_flow_enum)]
#![feature(let_chains)]
#![feature(lint_reasons)]
#![feature(never_type)]

View file

@ -327,7 +327,7 @@ fn is_assert_arg(cx: &LateContext<'_>, expr: &Expr<'_>, assert_expn: ExpnId) ->
} else {
match cx.tcx.item_name(macro_call.def_id) {
// `cfg!(debug_assertions)` in `debug_assert!`
sym::cfg => ControlFlow::CONTINUE,
sym::cfg => ControlFlow::Continue(()),
// assert!(other_macro!(..))
_ => ControlFlow::Break(true),
}

View file

@ -140,7 +140,7 @@ impl TypeVisitor<'_> for ContainsRegion {
type BreakTy = ();
fn visit_region(&mut self, _: ty::Region<'_>) -> ControlFlow<Self::BreakTy> {
ControlFlow::BREAK
ControlFlow::Break(())
}
}

View file

@ -0,0 +1 @@
missing_message_ref = {message}

View file

@ -96,3 +96,12 @@ mod missing_crate_name {
use self::fluent_generated::{DEFAULT_LOCALE_RESOURCES, test_crate_foo, with_hyphens};
}
mod missing_message_ref {
use super::fluent_messages;
fluent_messages! {
missing => "./missing-message-ref.ftl"
//~^ ERROR referenced message `message` does not exist
}
}

View file

@ -93,6 +93,14 @@ LL | test_crate => "./missing-crate-name.ftl",
|
= help: replace any '-'s with '_'s
error: aborting due to 10 previous errors
error: referenced message `message` does not exist (in message `missing_message_ref`)
--> $DIR/test.rs:104:20
|
LL | missing => "./missing-message-ref.ftl"
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: you may have meant to use a variable reference (`{$message}`)
error: aborting due to 11 previous errors
For more information about this error, try `rustc --explain E0428`.

View file

@ -0,0 +1,24 @@
#![feature(let_chains)]
trait Demo {}
impl dyn Demo {
pub fn report(&self) -> u32 {
let sum = |a: u32,
b: u32,
c: u32| {
a + b + c
};
sum(1, 2, 3)
}
fn check(&self, val: Option<u32>, num: Option<u32>) {
if let Some(b) = val
&& let Some(c) = num {
&& b == c {
//~^ ERROR expected struct
//~| ERROR mismatched types
}
}
}
fn main() { } //~ ERROR this file contains an unclosed delimiter

View file

@ -0,0 +1,37 @@
error: this file contains an unclosed delimiter
--> $DIR/deli-ident-issue-1.rs:24:66
|
LL | impl dyn Demo {
| - unclosed delimiter
...
LL | && let Some(c) = num {
| - this delimiter might not be properly closed...
...
LL | }
| - ...as it matches this but it has different indentation
...
LL | fn main() { }
| ^
error[E0574]: expected struct, variant or union type, found local variable `c`
--> $DIR/deli-ident-issue-1.rs:17:17
|
LL | && b == c {
| ^ not a struct, variant or union type
error[E0308]: mismatched types
--> $DIR/deli-ident-issue-1.rs:17:9
|
LL | fn check(&self, val: Option<u32>, num: Option<u32>) {
| - expected `()` because of default return type
...
LL | / && b == c {
LL | |
LL | |
LL | | }
| |_________^ expected `()`, found `bool`
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0308, E0574.
For more information about an error, try `rustc --explain E0308`.

View file

@ -0,0 +1,7 @@
fn main() {
if 1 < 2 {
let _a = vec!]; //~ ERROR mismatched closing delimiter
}
} //~ ERROR unexpected closing delimiter
fn main() {}

View file

@ -0,0 +1,19 @@
error: unexpected closing delimiter: `}`
--> $DIR/deli-ident-issue-2.rs:5:1
|
LL | let _a = vec!];
| - missing open `[` for this delimiter
LL | }
LL | }
| ^ unexpected closing delimiter
error: mismatched closing delimiter: `]`
--> $DIR/deli-ident-issue-2.rs:2:14
|
LL | if 1 < 2 {
| ^ unclosed delimiter
LL | let _a = vec!];
| ^ mismatched closing delimiter
error: aborting due to 2 previous errors

View file

@ -0,0 +1,12 @@
// This file has unexpected closing delimiter,
fn func(o: Option<u32>) {
match o {
Some(_x) => {} // Extra '}'
let _ = if true {};
}
None => {}
}
} //~ ERROR unexpected closing delimiter
fn main() {}

View file

@ -0,0 +1,16 @@
error: unexpected closing delimiter: `}`
--> $DIR/issue-68987-unmatch-issue-1.rs:10:1
|
LL | match o {
| - this delimiter might not be properly closed...
LL | Some(_x) => {} // Extra '}'
| -- block is empty, you might have not meant to close it
LL | let _ = if true {};
LL | }
| - ...as it matches this but it has different indentation
...
LL | }
| ^ unexpected closing delimiter
error: aborting due to previous error

View file

@ -0,0 +1,14 @@
// FIXME: this case need more work to fix
// currently the TokenTree matching ')' with '{', which is not user friendly for diagnostics
async fn obstest() -> Result<> {
let obs_connect = || -> Result<(), MyError) { //~ ERROR mismatched closing delimiter
async {
}
}
if let Ok(version, scene_list) = obs_connect() {
} else {
}
} //~ ERROR unexpected closing delimiter

View file

@ -0,0 +1,19 @@
error: unexpected closing delimiter: `}`
--> $DIR/issue-68987-unmatch-issue-2.rs:14:1
|
LL | let obs_connect = || -> Result<(), MyError) {
| - missing open `(` for this delimiter
...
LL | }
| ^ unexpected closing delimiter
error: mismatched closing delimiter: `)`
--> $DIR/issue-68987-unmatch-issue-2.rs:3:32
|
LL | async fn obstest() -> Result<> {
| ^ unclosed delimiter
LL | let obs_connect = || -> Result<(), MyError) {
| ^ mismatched closing delimiter
error: aborting due to 2 previous errors

View file

@ -0,0 +1,8 @@
// the `{` is closed with `)`, there is a missing `(`
fn f(i: u32, j: u32) {
let res = String::new();
let mut cnt = i;
while cnt < j {
write!&mut res, " "); //~ ERROR mismatched closing delimiter
}
} //~ ERROR unexpected closing delimiter

View file

@ -0,0 +1,19 @@
error: unexpected closing delimiter: `}`
--> $DIR/issue-68987-unmatch-issue-3.rs:8:1
|
LL | write!&mut res, " ");
| - missing open `(` for this delimiter
LL | }
LL | }
| ^ unexpected closing delimiter
error: mismatched closing delimiter: `)`
--> $DIR/issue-68987-unmatch-issue-3.rs:5:19
|
LL | while cnt < j {
| ^ unclosed delimiter
LL | write!&mut res, " ");
| ^ mismatched closing delimiter
error: aborting due to 2 previous errors

View file

@ -0,0 +1,12 @@
// This file has unexpected closing delimiter,
fn func(o: Option<u32>) {
match o {
Some(_x) => // Missing '{'
let _ = if true {};
}
None => {}
}
} //~ ERROR unexpected closing delimiter
fn main() {}

View file

@ -0,0 +1,16 @@
error: unexpected closing delimiter: `}`
--> $DIR/issue-68987-unmatch-issue.rs:10:1
|
LL | match o {
| - this delimiter might not be properly closed...
LL | Some(_x) => // Missing '{'
LL | let _ = if true {};
| -- block is empty, you might have not meant to close it
LL | }
| - ...as it matches this but it has different indentation
...
LL | }
| ^ unexpected closing delimiter
error: aborting due to previous error

View file

@ -2,8 +2,9 @@ error: this file contains an unclosed delimiter
--> $DIR/issue-81827.rs:11:27
|
LL | fn r()->i{0|{#[cfg(r(0{]0
| - - ^
| | |
| - - - ^
| | | |
| | | missing open `[` for this delimiter
| | unclosed delimiter
| unclosed delimiter
@ -11,8 +12,9 @@ error: this file contains an unclosed delimiter
--> $DIR/issue-81827.rs:11:27
|
LL | fn r()->i{0|{#[cfg(r(0{]0
| - - ^
| | |
| - - - ^
| | | |
| | | missing open `[` for this delimiter
| | unclosed delimiter
| unclosed delimiter

View file

@ -2,8 +2,10 @@ error: this file contains an unclosed delimiter
--> $DIR/issue-62973.rs:8:2
|
LL | fn p() { match s { v, E { [) {) }
| - - unclosed delimiter
| |
| - - - - missing open `(` for this delimiter
| | | |
| | | missing open `(` for this delimiter
| | unclosed delimiter
| unclosed delimiter
LL |
LL |
@ -13,8 +15,10 @@ error: this file contains an unclosed delimiter
--> $DIR/issue-62973.rs:8:2
|
LL | fn p() { match s { v, E { [) {) }
| - - unclosed delimiter
| |
| - - - - missing open `(` for this delimiter
| | | |
| | | missing open `(` for this delimiter
| | unclosed delimiter
| unclosed delimiter
LL |
LL |

View file

@ -2,8 +2,9 @@ error: this file contains an unclosed delimiter
--> $DIR/issue-63116.rs:3:18
|
LL | impl W <s(f;Y(;]
| - ^
| |
| - - ^
| | |
| | missing open `[` for this delimiter
| unclosed delimiter
error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `;`

View file

@ -0,0 +1,3 @@
fn main() {}
fn f) {} //~ ERROR unexpected closing delimiter

View file

@ -0,0 +1,8 @@
error: unexpected closing delimiter: `)`
--> $DIR/issue-69259.rs:3:5
|
LL | fn f) {}
| ^ unexpected closing delimiter
error: aborting due to previous error

View file

@ -2,10 +2,10 @@ error: unexpected closing delimiter: `}`
--> $DIR/issue-70583-block-is-empty-1.rs:20:1
|
LL | fn struct_generic(x: Vec<i32>) {
| - this opening brace...
| - this delimiter might not be properly closed...
...
LL | }
| - ...matches this closing brace
| - ...as it matches this but it has different indentation
LL | }
| ^ unexpected closing delimiter

View file

@ -1,8 +1,12 @@
error: unexpected closing delimiter: `}`
--> $DIR/issue-70583-block-is-empty-2.rs:14:1
|
LL | match self {
| - this delimiter might not be properly closed...
LL | ErrorHandled::Reported => {}}
| -- block is empty, you might have not meant to close it
| --- ...as it matches this but it has different indentation
| |
| block is empty, you might have not meant to close it
...
LL | }
| ^ unexpected closing delimiter

View file

@ -2,10 +2,10 @@ error: unexpected closing delimiter: `}`
--> $DIR/macro-mismatched-delim-paren-brace.rs:5:1
|
LL | fn main() {
| - this opening brace...
| - this delimiter might not be properly closed...
...
LL | }
| - ...matches this closing brace
| - ...as it matches this but it has different indentation
LL | }
| ^ unexpected closing delimiter

View file

@ -0,0 +1,12 @@
// check-pass
#![feature(trait_alias)]
struct MyStruct {}
trait MyFn = Fn(&MyStruct);
fn foo(_: impl MyFn) {}
fn main() {
foo(|_| {});
}

View file

@ -2,8 +2,9 @@ error: this file contains an unclosed delimiter
--> $DIR/issue-91334.rs:10:23
|
LL | fn f(){||yield(((){),
| - - ^
| | |
| - - - ^
| | | |
| | | missing open `(` for this delimiter
| | unclosed delimiter
| unclosed delimiter
@ -11,8 +12,9 @@ error: this file contains an unclosed delimiter
--> $DIR/issue-91334.rs:10:23
|
LL | fn f(){||yield(((){),
| - - ^
| | |
| - - - ^
| | | |
| | | missing open `(` for this delimiter
| | unclosed delimiter
| unclosed delimiter