diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_gcc.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_gcc.ftl index 08ce5172574ac..6101b28ab0cdd 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_gcc.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_gcc.ftl @@ -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}` diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl index c8c7afb5f9196..4924105128db6 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -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 diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 72676b718fabe..a567b6acdbeeb 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -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> { - 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>( - &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) - } +impl<'tcx> FallibleTypeFolder<'tcx> for ConstInferUnifier<'_, 'tcx> { + type Error = TypeError<'tcx>; - fn binders( - &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())?)) + fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { + self.infcx.tcx } #[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, 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, 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, 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), } } } diff --git a/compiler/rustc_macros/src/diagnostics/fluent.rs b/compiler/rustc_macros/src/diagnostics/fluent.rs index 32338f9dfc5e3..08098c9bb2a85 100644 --- a/compiler/rustc_macros/src/diagnostics/fluent.rs +++ b/compiler/rustc_macros/src/diagnostics/fluent.rs @@ -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 { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 4af29fcbfb586..7001f81aa7750 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -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>>); -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 (`'_`). diff --git a/compiler/rustc_parse/src/lexer/diagnostics.rs b/compiler/rustc_parse/src/lexer/diagnostics.rs new file mode 100644 index 0000000000000..386bf026bb4af --- /dev/null +++ b/compiler/rustc_parse/src/lexer/diagnostics.rs @@ -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, + + /// Used only for error recovery when arriving to EOF with mismatched braces. + pub last_unclosed_found_span: Option, + + /// Collect empty block spans that might have been auto-inserted by editors. + pub empty_block_spans: Vec, + + /// 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"); + } + } +} diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 9fe8d9836ba60..e957224a03377 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -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; diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs index b2701817d489b..0de8f79112c65 100644 --- a/compiler/rustc_parse/src/lexer/tokentrees.rs +++ b/compiler/rustc_parse/src/lexer/tokentrees.rs @@ -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, - /// 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, - /// Collect empty block spans that might have been auto-inserted by editors. - last_delim_empty_block_spans: FxHashMap, - /// 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 } diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 638efaa2ba5d2..1961344e8385f 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -93,24 +93,24 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { 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 { 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(()) } } } diff --git a/library/core/src/iter/adapters/filter_map.rs b/library/core/src/iter/adapters/filter_map.rs index e0d665c9e12ba..6bdf53f7fc9dd 100644 --- a/library/core/src/iter/adapters/filter_map.rs +++ b/library/core/src/iter/adapters/filter_map.rs @@ -99,7 +99,7 @@ where ) -> impl FnMut((), T) -> ControlFlow + '_ { move |(), x| match f(x) { Some(x) => ControlFlow::Break(x), - None => ControlFlow::CONTINUE, + None => ControlFlow::Continue(()), } } diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index 307016c269099..b040a0ea9011b 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -539,7 +539,7 @@ where #[rustc_inherit_overflow_checks] fn advance(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(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), } } diff --git a/library/core/src/iter/traits/double_ended.rs b/library/core/src/iter/traits/double_ended.rs index bdf94c792c27c..ed23873cdde7c 100644 --- a/library/core/src/iter/traits/double_ended.rs +++ b/library/core/src/iter/traits/double_ended.rs @@ -352,7 +352,7 @@ pub trait DoubleEndedIterator: Iterator { #[inline] fn check(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut((), T) -> ControlFlow { move |(), x| { - if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::CONTINUE } + if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::Continue(()) } } } diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index a4a665d48d58c..5a0b8594104ee 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -2601,10 +2601,10 @@ pub trait Iterator { #[inline] fn check(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(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(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut((), T) -> ControlFlow { 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(mut f: impl FnMut(T) -> Option) -> impl FnMut((), T) -> ControlFlow { 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>, { 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, { 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 diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index cd183540cd5e9..117706fb4b28d 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -259,46 +259,3 @@ impl ControlFlow { } } } - -impl ControlFlow { - /// 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 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(()); -} diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index eb582be012bd5..839fdc96632d1 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -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) => { diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 99cc018631048..762f7a7c9a1a0 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -358,7 +358,6 @@ #![feature(const_ip)] #![feature(const_ipv4)] #![feature(const_ipv6)] -#![feature(const_socketaddr)] #![feature(thread_local_internals)] // #![default_lib_allocator] diff --git a/library/std/src/net/socket_addr.rs b/library/std/src/net/socket_addr.rs index 33b0dfa03e0ed..1264bae809b26 100644 --- a/library/std/src/net/socket_addr.rs +++ b/library/std/src/net/socket_addr.rs @@ -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 } diff --git a/library/std/src/personality/emcc.rs b/library/std/src/personality/emcc.rs index f942bdf18c180..cb52ae89b1911 100644 --- a/library/std/src/personality/emcc.rs +++ b/library/std/src/personality/emcc.rs @@ -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 diff --git a/library/std/src/personality/gcc.rs b/library/std/src/personality/gcc.rs index 5fc1b91a1c357..41c0fe725a540 100644 --- a/library/std/src/personality/gcc.rs +++ b/library/std/src/personality/gcc.rs @@ -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() diff --git a/library/std/src/sys/windows/thread_parking.rs b/library/std/src/sys/windows/thread_parking.rs index 5d43676adbb11..eb9167cd8552b 100644 --- a/library/std/src/sys/windows/thread_parking.rs +++ b/library/std/src/sys/windows/thread_parking.rs @@ -221,7 +221,7 @@ impl Parker { fn keyed_event_handle() -> c::HANDLE { const INVALID: c::HANDLE = ptr::invalid_mut(!0); - static HANDLE: AtomicPtr = AtomicPtr::new(INVALID); + static HANDLE: AtomicPtr = AtomicPtr::new(INVALID); match HANDLE.load(Relaxed) { INVALID => { let mut handle = c::INVALID_HANDLE_VALUE; diff --git a/library/std/src/sys_common/net.rs b/library/std/src/sys_common/net.rs index fad4a63331b59..2c38dfecf9734 100644 --- a/library/std/src/sys_common/net.rs +++ b/library/std/src/sys_common/net.rs @@ -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 } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/librustdoc/html/length_limit.rs b/src/librustdoc/html/length_limit.rs index bbdc91c8d2ec8..4c8db2c6784a5 100644 --- a/src/librustdoc/html/length_limit.rs +++ b/src/librustdoc/html/length_limit.rs @@ -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. diff --git a/src/librustdoc/html/length_limit/tests.rs b/src/librustdoc/html/length_limit/tests.rs index 2d02b8a16da67..2185c034890fa 100644 --- a/src/librustdoc/html/length_limit/tests.rs +++ b/src/librustdoc/html/length_limit/tests.rs @@ -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!( diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index d7739b8534f30..00e3f859bfcb3 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -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) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 604ab147f6a16..b9ad8ef70e917 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -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 = []; diff --git a/src/librustdoc/html/templates/print_item.html b/src/librustdoc/html/templates/print_item.html index ee2880bf6d195..3a1867b7feba3 100644 --- a/src/librustdoc/html/templates/print_item.html +++ b/src/librustdoc/html/templates/print_item.html @@ -6,7 +6,7 @@

{#- -#} {{component.name}}:: {%- endfor -%} {{name}} {#- -#} -