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:
commit
bca8b4dc32
57 changed files with 557 additions and 312 deletions
|
@ -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}`
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 (`'_`).
|
||||
|
|
119
compiler/rustc_parse/src/lexer/diagnostics.rs
Normal file
119
compiler/rustc_parse/src/lexer/diagnostics.rs
Normal 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");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(()) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(());
|
||||
}
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -358,7 +358,6 @@
|
|||
#![feature(const_ip)]
|
||||
#![feature(const_ipv4)]
|
||||
#![feature(const_ipv6)]
|
||||
#![feature(const_socketaddr)]
|
||||
#![feature(thread_local_internals)]
|
||||
//
|
||||
#![default_lib_allocator]
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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!(
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 = [];
|
||||
|
||||
|
|
|
@ -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"> {#- -#}
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -54,7 +54,7 @@ fn collect_replace_calls<'tcx>(
|
|||
from_args.push_front(from);
|
||||
ControlFlow::Continue(())
|
||||
} else {
|
||||
ControlFlow::BREAK
|
||||
ControlFlow::Break(())
|
||||
}
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#![feature(array_chunks)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(lint_reasons)]
|
||||
#![feature(never_type)]
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
|
|
|
@ -140,7 +140,7 @@ impl TypeVisitor<'_> for ContainsRegion {
|
|||
type BreakTy = ();
|
||||
|
||||
fn visit_region(&mut self, _: ty::Region<'_>) -> ControlFlow<Self::BreakTy> {
|
||||
ControlFlow::BREAK
|
||||
ControlFlow::Break(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
missing_message_ref = {message}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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`.
|
||||
|
|
24
tests/ui/parser/deli-ident-issue-1.rs
Normal file
24
tests/ui/parser/deli-ident-issue-1.rs
Normal 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
|
37
tests/ui/parser/deli-ident-issue-1.stderr
Normal file
37
tests/ui/parser/deli-ident-issue-1.stderr
Normal 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`.
|
7
tests/ui/parser/deli-ident-issue-2.rs
Normal file
7
tests/ui/parser/deli-ident-issue-2.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
fn main() {
|
||||
if 1 < 2 {
|
||||
let _a = vec!]; //~ ERROR mismatched closing delimiter
|
||||
}
|
||||
} //~ ERROR unexpected closing delimiter
|
||||
|
||||
fn main() {}
|
19
tests/ui/parser/deli-ident-issue-2.stderr
Normal file
19
tests/ui/parser/deli-ident-issue-2.stderr
Normal 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
|
||||
|
12
tests/ui/parser/issue-68987-unmatch-issue-1.rs
Normal file
12
tests/ui/parser/issue-68987-unmatch-issue-1.rs
Normal 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() {}
|
16
tests/ui/parser/issue-68987-unmatch-issue-1.stderr
Normal file
16
tests/ui/parser/issue-68987-unmatch-issue-1.stderr
Normal 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
|
||||
|
14
tests/ui/parser/issue-68987-unmatch-issue-2.rs
Normal file
14
tests/ui/parser/issue-68987-unmatch-issue-2.rs
Normal 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
|
19
tests/ui/parser/issue-68987-unmatch-issue-2.stderr
Normal file
19
tests/ui/parser/issue-68987-unmatch-issue-2.stderr
Normal 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
|
||||
|
8
tests/ui/parser/issue-68987-unmatch-issue-3.rs
Normal file
8
tests/ui/parser/issue-68987-unmatch-issue-3.rs
Normal 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
|
19
tests/ui/parser/issue-68987-unmatch-issue-3.stderr
Normal file
19
tests/ui/parser/issue-68987-unmatch-issue-3.stderr
Normal 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
|
||||
|
12
tests/ui/parser/issue-68987-unmatch-issue.rs
Normal file
12
tests/ui/parser/issue-68987-unmatch-issue.rs
Normal 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() {}
|
16
tests/ui/parser/issue-68987-unmatch-issue.stderr
Normal file
16
tests/ui/parser/issue-68987-unmatch-issue.stderr
Normal 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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 |
|
||||
|
|
|
@ -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 `;`
|
||||
|
|
3
tests/ui/parser/issues/issue-69259.rs
Normal file
3
tests/ui/parser/issues/issue-69259.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
fn main() {}
|
||||
|
||||
fn f) {} //~ ERROR unexpected closing delimiter
|
8
tests/ui/parser/issues/issue-69259.stderr
Normal file
8
tests/ui/parser/issues/issue-69259.stderr
Normal 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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
12
tests/ui/traits/alias/issue-60755.rs
Normal file
12
tests/ui/traits/alias/issue-60755.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
// check-pass
|
||||
|
||||
#![feature(trait_alias)]
|
||||
|
||||
struct MyStruct {}
|
||||
trait MyFn = Fn(&MyStruct);
|
||||
|
||||
fn foo(_: impl MyFn) {}
|
||||
|
||||
fn main() {
|
||||
foo(|_| {});
|
||||
}
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue