diff options
24 files changed, 302 insertions, 135 deletions
diff --git a/Cargo.toml b/Cargo.toml index ed024192c15..ffc886d47f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,7 +60,7 @@ exclude = [ # verify that this is the case. This requires, however, that the crate is built # without overflow checks and debug assertions. Forcefully disable debug # assertions and overflow checks here which should ensure that even if these -# assertions are enabled for libstd we won't enable then for compiler_builtins +# assertions are enabled for libstd we won't enable them for compiler_builtins # which should ensure we still link everything correctly. debug-assertions = false overflow-checks = false diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 2b941ec6809..ccc29adc015 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -129,7 +129,7 @@ fn get_features( .span_suggestion( mi.span(), "expected just one word", - format!("{}", ident.name), + ident.name, Applicability::MaybeIncorrect, ) .emit(); diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 87bc0d9762e..a14a7fc0610 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1677,7 +1677,6 @@ impl<'a> Parser<'a> { } /// Is this a possibly malformed start of a `macro_rules! foo` item definition? - fn is_macro_rules_item(&mut self) -> IsMacroRulesItem { if self.check_keyword(kw::MacroRules) { let macro_rules_span = self.token.span; diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 0343e8d9b8e..22a307a15ed 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -2023,7 +2023,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { span: Span, mut path: Vec<Segment>, parent_scope: &ParentScope<'b>, - ) -> Option<(Vec<Segment>, Vec<String>)> { + ) -> Option<(Vec<Segment>, Option<String>)> { debug!("make_path_suggestion: span={:?} path={:?}", span, path); match (path.get(0), path.get(1)) { @@ -2058,12 +2058,12 @@ impl<'a, 'b> ImportResolver<'a, 'b> { &mut self, mut path: Vec<Segment>, parent_scope: &ParentScope<'b>, - ) -> Option<(Vec<Segment>, Vec<String>)> { + ) -> Option<(Vec<Segment>, Option<String>)> { // Replace first ident with `self` and check if that is valid. path[0].ident.name = kw::SelfLower; let result = self.r.maybe_resolve_path(&path, None, parent_scope); debug!("make_missing_self_suggestion: path={:?} result={:?}", path, result); - if let PathResult::Module(..) = result { Some((path, Vec::new())) } else { None } + if let PathResult::Module(..) = result { Some((path, None)) } else { None } } /// Suggests a missing `crate::` if that resolves to an correct module. @@ -2077,7 +2077,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { &mut self, mut path: Vec<Segment>, parent_scope: &ParentScope<'b>, - ) -> Option<(Vec<Segment>, Vec<String>)> { + ) -> Option<(Vec<Segment>, Option<String>)> { // Replace first ident with `crate` and check if that is valid. path[0].ident.name = kw::Crate; let result = self.r.maybe_resolve_path(&path, None, parent_scope); @@ -2085,12 +2085,12 @@ impl<'a, 'b> ImportResolver<'a, 'b> { if let PathResult::Module(..) = result { Some(( path, - vec![ + Some( "`use` statements changed in Rust 2018; read more at \ <https://doc.rust-lang.org/edition-guide/rust-2018/module-system/path-\ clarity.html>" .to_string(), - ], + ), )) } else { None @@ -2108,12 +2108,12 @@ impl<'a, 'b> ImportResolver<'a, 'b> { &mut self, mut path: Vec<Segment>, parent_scope: &ParentScope<'b>, - ) -> Option<(Vec<Segment>, Vec<String>)> { + ) -> Option<(Vec<Segment>, Option<String>)> { // Replace first ident with `crate` and check if that is valid. path[0].ident.name = kw::Super; let result = self.r.maybe_resolve_path(&path, None, parent_scope); debug!("make_missing_super_suggestion: path={:?} result={:?}", path, result); - if let PathResult::Module(..) = result { Some((path, Vec::new())) } else { None } + if let PathResult::Module(..) = result { Some((path, None)) } else { None } } /// Suggests a missing external crate name if that resolves to an correct module. @@ -2130,7 +2130,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { &mut self, mut path: Vec<Segment>, parent_scope: &ParentScope<'b>, - ) -> Option<(Vec<Segment>, Vec<String>)> { + ) -> Option<(Vec<Segment>, Option<String>)> { if path[1].ident.span.rust_2015() { return None; } @@ -2151,7 +2151,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { name, path, result ); if let PathResult::Module(..) = result { - return Some((path, Vec::new())); + return Some((path, None)); } } @@ -2175,7 +2175,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { import: &'b Import<'b>, module: ModuleOrUniformRoot<'b>, ident: Ident, - ) -> Option<(Option<Suggestion>, Vec<String>)> { + ) -> Option<(Option<Suggestion>, Option<String>)> { let ModuleOrUniformRoot::Module(mut crate_module) = module else { return None; }; @@ -2287,12 +2287,9 @@ impl<'a, 'b> ImportResolver<'a, 'b> { String::from("a macro with this name exists at the root of the crate"), Applicability::MaybeIncorrect, )); - let note = vec![ - "this could be because a macro annotated with `#[macro_export]` will be exported \ - at the root of the crate instead of the module where it is defined" - .to_string(), - ]; - Some((suggestion, note)) + Some((suggestion, Some("this could be because a macro annotated with `#[macro_export]` will be exported \ + at the root of the crate instead of the module where it is defined" + .to_string()))) } else { None } diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index e6060ad4665..b89273990d8 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -336,7 +336,7 @@ impl<'a> Resolver<'a> { struct UnresolvedImportError { span: Span, label: Option<String>, - note: Vec<String>, + note: Option<String>, suggestion: Option<Suggestion>, } @@ -427,7 +427,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let err = UnresolvedImportError { span: import.span, label: None, - note: Vec::new(), + note: None, suggestion: None, }; if path.contains("::") { @@ -463,10 +463,8 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let mut diag = struct_span_err!(self.r.session, span, E0432, "{}", &msg); - if let Some((_, UnresolvedImportError { note, .. })) = errors.iter().last() { - for message in note { - diag.note(message); - } + if let Some((_, UnresolvedImportError { note: Some(note), .. })) = errors.iter().last() { + diag.note(note); } for (_, err) in errors.into_iter().take(MAX_LABEL_COUNT) { @@ -644,7 +642,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { None => UnresolvedImportError { span, label: Some(label), - note: Vec::new(), + note: None, suggestion, }, }; @@ -686,7 +684,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { return Some(UnresolvedImportError { span: import.span, label: Some(String::from("cannot glob-import a module into itself")), - note: Vec::new(), + note: None, suggestion: None, }); } @@ -830,7 +828,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let (suggestion, note) = match self.check_for_module_export_macro(import, module, ident) { Some((suggestion, note)) => (suggestion.or(lev_suggestion), note), - _ => (lev_suggestion, Vec::new()), + _ => (lev_suggestion, None), }; let label = match module { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 89d7c050c40..6c8faed0df4 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -184,7 +184,7 @@ pub trait InferCtxtExt<'tcx> { trait_pred: ty::PolyTraitPredicate<'tcx>, ) -> bool; - fn get_closure_name(&self, def_id: DefId, err: &mut Diagnostic, msg: &str) -> Option<String>; + fn get_closure_name(&self, def_id: DefId, err: &mut Diagnostic, msg: &str) -> Option<Symbol>; fn suggest_fn_call( &self, @@ -737,13 +737,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { /// Given a closure's `DefId`, return the given name of the closure. /// /// This doesn't account for reassignments, but it's only used for suggestions. - fn get_closure_name(&self, def_id: DefId, err: &mut Diagnostic, msg: &str) -> Option<String> { - let get_name = |err: &mut Diagnostic, kind: &hir::PatKind<'_>| -> Option<String> { + fn get_closure_name(&self, def_id: DefId, err: &mut Diagnostic, msg: &str) -> Option<Symbol> { + let get_name = |err: &mut Diagnostic, kind: &hir::PatKind<'_>| -> Option<Symbol> { // Get the local name of this closure. This can be inaccurate because // of the possibility of reassignment, but this should be good enough. match &kind { - hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, name, None) => { - Some(format!("{}", name)) + hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, ident, None) => { + Some(ident.name) } _ => { err.note(msg); diff --git a/compiler/rustc_traits/src/evaluate_obligation.rs b/compiler/rustc_traits/src/evaluate_obligation.rs index 3fc141471b9..49c9ba45963 100644 --- a/compiler/rustc_traits/src/evaluate_obligation.rs +++ b/compiler/rustc_traits/src/evaluate_obligation.rs @@ -1,4 +1,4 @@ -use rustc_infer::infer::TyCtxtInferExt; +use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; use rustc_span::source_map::DUMMY_SP; @@ -16,7 +16,9 @@ fn evaluate_obligation<'tcx>( canonical_goal: CanonicalPredicateGoal<'tcx>, ) -> Result<EvaluationResult, OverflowError> { debug!("evaluate_obligation(canonical_goal={:#?})", canonical_goal); - tcx.infer_ctxt().enter_with_canonical( + // HACK This bubble is required for this tests to pass: + // impl-trait/issue99642.rs + tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).enter_with_canonical( DUMMY_SP, &canonical_goal, |ref infcx, goal, _canonical_inference_vars| { diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index f8bac1d7b26..d895b647db0 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -2,7 +2,7 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_infer::infer::at::ToTrace; use rustc_infer::infer::canonical::{Canonical, QueryResponse}; -use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; +use rustc_infer::infer::{DefiningAnchor, InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::TraitEngineExt as _; use rustc_middle::ty::query::Providers; use rustc_middle::ty::subst::{GenericArg, Subst, UserSelfTy, UserSubsts}; @@ -258,10 +258,15 @@ fn type_op_prove_predicate<'tcx>( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, ProvePredicate<'tcx>>>, ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, NoSolution> { - tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, |infcx, fulfill_cx, key| { - type_op_prove_predicate_with_cause(infcx, fulfill_cx, key, ObligationCause::dummy()); - Ok(()) - }) + // HACK This bubble is required for this test to pass: + // impl-trait/issue-99642.rs + tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).enter_canonical_trait_query( + &canonicalized, + |infcx, fulfill_cx, key| { + type_op_prove_predicate_with_cause(infcx, fulfill_cx, key, ObligationCause::dummy()); + Ok(()) + }, + ) } /// The core of the `type_op_prove_predicate` query: for diagnostics purposes in NLL HRTB errors, diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index 0bec38a877e..eae567cad00 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -892,7 +892,16 @@ impl char { /// /// The general categories for numbers (`Nd` for decimal digits, `Nl` for letter-like numeric /// characters, and `No` for other numeric characters) are specified in the [Unicode Character - /// Database][ucd] [`UnicodeData.txt`]. + /// Database][ucd] [`UnicodeData.txt`]. Note that this means ideographic numbers like '三' + /// are considered alphabetic, not numeric. Please consider to use `is_ascii_digit` or `is_digit`. + /// + /// This method doesn't cover everything that could be considered a number, e.g. ideographic numbers like '三'. + /// If you want everything including characters with overlapping purposes then you might want to use + /// a unicode or language-processing library that exposes the appropriate character properties instead + /// of looking at the unicode categories. + /// + /// If you want to parse ASCII decimal digits (0-9) or ASCII base-N, use + /// `is_ascii_digit` or `is_digit` instead. /// /// [Unicode Standard]: https://www.unicode.org/versions/latest/ /// [ucd]: https://www.unicode.org/reports/tr44/ @@ -911,6 +920,7 @@ impl char { /// assert!(!'K'.is_numeric()); /// assert!(!'و'.is_numeric()); /// assert!(!'藏'.is_numeric()); + /// assert!(!'三'.is_numeric()); /// ``` #[must_use] #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index bd62bc5c305..3a115a8b8b6 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -496,10 +496,9 @@ macro_rules! r#try { #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "write_macro")] macro_rules! write { - ($dst:expr, $($arg:tt)*) => {{ - let result = $dst.write_fmt($crate::format_args!($($arg)*)); - result - }}; + ($dst:expr, $($arg:tt)*) => { + $dst.write_fmt($crate::format_args!($($arg)*)) + }; } /// Write formatted data into a buffer, with a newline appended. @@ -554,10 +553,9 @@ macro_rules! writeln { ($dst:expr $(,)?) => { $crate::write!($dst, "\n") }; - ($dst:expr, $($arg:tt)*) => {{ - let result = $dst.write_fmt($crate::format_args_nl!($($arg)*)); - result - }}; + ($dst:expr, $($arg:tt)*) => { + $dst.write_fmt($crate::format_args_nl!($($arg)*)) + }; } /// Indicates unreachable code. diff --git a/library/std/src/os/fd/raw.rs b/library/std/src/os/fd/raw.rs index ff4e25b792a..081915ed148 100644 --- a/library/std/src/os/fd/raw.rs +++ b/library/std/src/os/fd/raw.rs @@ -14,6 +14,7 @@ use crate::os::wasi::io::OwnedFd; use crate::sys_common::{AsInner, IntoInner}; /// Raw file descriptors. +#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)] #[stable(feature = "rust1", since = "1.0.0")] pub type RawFd = raw::c_int; @@ -22,6 +23,7 @@ pub type RawFd = raw::c_int; /// This is only available on unix and WASI platforms and must be imported in /// order to call the method. Windows platforms have a corresponding /// `AsRawHandle` and `AsRawSocket` set of traits. +#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)] #[stable(feature = "rust1", since = "1.0.0")] pub trait AsRawFd { /// Extracts the raw file descriptor. @@ -57,6 +59,7 @@ pub trait AsRawFd { /// A trait to express the ability to construct an object from a raw file /// descriptor. +#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)] #[stable(feature = "from_raw_os", since = "1.1.0")] pub trait FromRawFd { /// Constructs a new instance of `Self` from the given raw file @@ -100,6 +103,7 @@ pub trait FromRawFd { /// A trait to express the ability to consume an object and acquire ownership of /// its raw file descriptor. +#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)] #[stable(feature = "into_raw_os", since = "1.4.0")] pub trait IntoRawFd { /// Consumes this object, returning the raw underlying file descriptor. diff --git a/library/std/src/os/wasi/io/raw.rs b/library/std/src/os/wasi/io/raw.rs index 0e0c5824e34..da3b36adad4 100644 --- a/library/std/src/os/wasi/io/raw.rs +++ b/library/std/src/os/wasi/io/raw.rs @@ -2,4 +2,19 @@ #![unstable(feature = "wasi_ext", issue = "71213")] +// NOTE: despite the fact that this module is unstable, +// stable Rust had the capability to access the stable +// re-exported items from os::fd::raw through this +// unstable module. +// In PR #95956 the stability checker was changed to check +// all path segments of an item rather than just the last, +// which caused the aforementioned stable usage to regress +// (see issue #99502). +// As a result, the items in os::fd::raw were given the +// rustc_allowed_through_unstable_modules attribute. +// No regression tests were added to ensure this property, +// as CI is not configured to test wasm32-wasi. +// If this module is stabilized, +// you may want to remove those attributes +// (assuming no other unstable modules need them). pub use crate::os::fd::raw::*; diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 2f3ca41723d..2f2fbc9d4ba 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -398,23 +398,19 @@ fn clean_type_outlives_predicate<'tcx>( }) } -impl<'tcx> Clean<'tcx, Term> for ty::Term<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Term { - match self { - ty::Term::Ty(ty) => Term::Type(clean_middle_ty(*ty, cx, None)), - ty::Term::Const(c) => Term::Constant(clean_middle_const(*c, cx)), - } +fn clean_middle_term<'tcx>(term: ty::Term<'tcx>, cx: &mut DocContext<'tcx>) -> Term { + match term { + ty::Term::Ty(ty) => Term::Type(clean_middle_ty(ty, cx, None)), + ty::Term::Const(c) => Term::Constant(clean_middle_const(c, cx)), } } -impl<'tcx> Clean<'tcx, Term> for hir::Term<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Term { - match self { - hir::Term::Ty(ty) => Term::Type(clean_ty(ty, cx)), - hir::Term::Const(c) => { - let def_id = cx.tcx.hir().local_def_id(c.hir_id); - Term::Constant(clean_middle_const(ty::Const::from_anon_const(cx.tcx, def_id), cx)) - } +fn clean_hir_term<'tcx>(term: &hir::Term<'tcx>, cx: &mut DocContext<'tcx>) -> Term { + match term { + hir::Term::Ty(ty) => Term::Type(clean_ty(ty, cx)), + hir::Term::Const(c) => { + let def_id = cx.tcx.hir().local_def_id(c.hir_id); + Term::Constant(clean_middle_const(ty::Const::from_anon_const(cx.tcx, def_id), cx)) } } } @@ -426,7 +422,7 @@ fn clean_projection_predicate<'tcx>( let ty::ProjectionPredicate { projection_ty, term } = pred; WherePredicate::EqPredicate { lhs: clean_projection(projection_ty, cx, None), - rhs: term.clean(cx), + rhs: clean_middle_term(term, cx), } } @@ -474,47 +470,44 @@ fn projection_to_path_segment<'tcx>( } } -impl<'tcx> Clean<'tcx, GenericParamDef> for ty::GenericParamDef { - fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericParamDef { - let (name, kind) = match self.kind { - ty::GenericParamDefKind::Lifetime => { - (self.name, GenericParamDefKind::Lifetime { outlives: vec![] }) - } - ty::GenericParamDefKind::Type { has_default, synthetic, .. } => { - let default = if has_default { - Some(clean_middle_ty(cx.tcx.type_of(self.def_id), cx, Some(self.def_id))) - } else { - None - }; - ( - self.name, - GenericParamDefKind::Type { - did: self.def_id, - bounds: vec![], // These are filled in from the where-clauses. - default: default.map(Box::new), - synthetic, - }, - ) - } - ty::GenericParamDefKind::Const { has_default } => ( - self.name, - GenericParamDefKind::Const { - did: self.def_id, - ty: Box::new(clean_middle_ty( - cx.tcx.type_of(self.def_id), - cx, - Some(self.def_id), - )), - default: match has_default { - true => Some(Box::new(cx.tcx.const_param_default(self.def_id).to_string())), - false => None, - }, +fn clean_generic_param_def<'tcx>( + def: &ty::GenericParamDef, + cx: &mut DocContext<'tcx>, +) -> GenericParamDef { + let (name, kind) = match def.kind { + ty::GenericParamDefKind::Lifetime => { + (def.name, GenericParamDefKind::Lifetime { outlives: vec![] }) + } + ty::GenericParamDefKind::Type { has_default, synthetic, .. } => { + let default = if has_default { + Some(clean_middle_ty(cx.tcx.type_of(def.def_id), cx, Some(def.def_id))) + } else { + None + }; + ( + def.name, + GenericParamDefKind::Type { + did: def.def_id, + bounds: vec![], // These are filled in from the where-clauses. + default: default.map(Box::new), + synthetic, }, - ), - }; + ) + } + ty::GenericParamDefKind::Const { has_default } => ( + def.name, + GenericParamDefKind::Const { + did: def.def_id, + ty: Box::new(clean_middle_ty(cx.tcx.type_of(def.def_id), cx, Some(def.def_id))), + default: match has_default { + true => Some(Box::new(cx.tcx.const_param_default(def.def_id).to_string())), + false => None, + }, + }, + ), + }; - GenericParamDef { name, kind } - } + GenericParamDef { name, kind } } fn clean_generic_param<'tcx>( @@ -672,7 +665,7 @@ fn clean_ty_generics<'tcx>( .iter() .filter_map(|param| match param.kind { ty::GenericParamDefKind::Lifetime if param.name == kw::UnderscoreLifetime => None, - ty::GenericParamDefKind::Lifetime => Some(param.clean(cx)), + ty::GenericParamDefKind::Lifetime => Some(clean_generic_param_def(param, cx)), ty::GenericParamDefKind::Type { synthetic, .. } => { if param.name == kw::SelfUpper { assert_eq!(param.index, 0); @@ -682,9 +675,9 @@ fn clean_ty_generics<'tcx>( impl_trait.insert(param.index.into(), vec![]); return None; } - Some(param.clean(cx)) + Some(clean_generic_param_def(param, cx)) } - ty::GenericParamDefKind::Const { .. } => Some(param.clean(cx)), + ty::GenericParamDefKind::Const { .. } => Some(clean_generic_param_def(param, cx)), }) .collect::<Vec<GenericParamDef>>(); @@ -1682,7 +1675,9 @@ pub(crate) fn clean_middle_ty<'tcx>( .projection_ty, cx, ), - kind: TypeBindingKind::Equality { term: pb.skip_binder().term.clean(cx) }, + kind: TypeBindingKind::Equality { + term: clean_middle_term(pb.skip_binder().term, cx), + }, }); } @@ -1746,7 +1741,7 @@ pub(crate) fn clean_middle_ty<'tcx>( Some(TypeBinding { assoc: projection_to_path_segment(proj.projection_ty, cx), kind: TypeBindingKind::Equality { - term: proj.term.clean(cx), + term: clean_middle_term(proj.term, cx), }, }) } else { @@ -2283,7 +2278,7 @@ impl<'tcx> Clean<'tcx, TypeBindingKind> for hir::TypeBindingKind<'tcx> { fn clean(&self, cx: &mut DocContext<'tcx>) -> TypeBindingKind { match *self { hir::TypeBindingKind::Equality { ref term } => { - TypeBindingKind::Equality { term: term.clean(cx) } + TypeBindingKind::Equality { term: clean_hir_term(term, cx) } } hir::TypeBindingKind::Constraint { bounds } => TypeBindingKind::Constraint { bounds: bounds.iter().filter_map(|b| b.clean(cx)).collect(), diff --git a/src/librustdoc/html/static/css/settings.css b/src/librustdoc/html/static/css/settings.css index e531e6ce6bb..e82ec042637 100644 --- a/src/librustdoc/html/static/css/settings.css +++ b/src/librustdoc/html/static/css/settings.css @@ -41,9 +41,7 @@ .toggle { position: relative; - display: inline-block; width: 100%; - height: 27px; margin-right: 20px; display: flex; align-items: center; @@ -58,6 +56,7 @@ .slider { position: relative; width: 45px; + min-width: 45px; display: block; height: 28px; margin-right: 20px; diff --git a/src/test/rustdoc-gui/settings.goml b/src/test/rustdoc-gui/settings.goml index 8a3365d3cc2..d9cf5ee6614 100644 --- a/src/test/rustdoc-gui/settings.goml +++ b/src/test/rustdoc-gui/settings.goml @@ -147,3 +147,12 @@ assert-false: "noscript section" javascript: false reload: assert-css: ("noscript section", {"display": "block"}) +javascript: true + +// Check for the display on small screen +show-text: true +reload: +size: (300, 1000) +click: "#settings-menu" +wait-for: "#settings" +assert-css: ("#settings .slider", {"width": "45px"}, ALL) diff --git a/src/test/ui/impl-trait/issue-99642-2.rs b/src/test/ui/impl-trait/issue-99642-2.rs new file mode 100644 index 00000000000..0e88b363338 --- /dev/null +++ b/src/test/ui/impl-trait/issue-99642-2.rs @@ -0,0 +1,8 @@ +// check-pass + +#![feature(type_alias_impl_trait)] +type Opq = impl Sized; +fn test() -> impl Iterator<Item = Opq> { + Box::new(0..) as Box<dyn Iterator<Item = _>> +} +fn main(){} diff --git a/src/test/ui/impl-trait/issue-99642.rs b/src/test/ui/impl-trait/issue-99642.rs new file mode 100644 index 00000000000..75af60491e4 --- /dev/null +++ b/src/test/ui/impl-trait/issue-99642.rs @@ -0,0 +1,7 @@ +// check-pass + +fn test() -> impl Iterator<Item = impl Sized> { + Box::new(0..) as Box<dyn Iterator<Item = _>> +} + +fn main() {} diff --git a/src/test/ui/linkage-attr/issue-10755.rs b/src/test/ui/linkage-attr/issue-10755.rs index 5ce69bceed3..afd2dc46ca3 100644 --- a/src/test/ui/linkage-attr/issue-10755.rs +++ b/src/test/ui/linkage-attr/issue-10755.rs @@ -1,7 +1,10 @@ // build-fail // dont-check-compiler-stderr // compile-flags: -C linker=llllll -C linker-flavor=ld -// error-pattern: linker `llllll` not found +// error-pattern: `llllll` + +// Before, the error-pattern checked for "not found". On WSL with appendWindowsPath=true, running +// in invalid command returns a PermissionDenied instead. fn main() { } diff --git a/src/test/ui/macros/format-args-temporaries-async.rs b/src/test/ui/macros/format-args-temporaries-async.rs new file mode 100644 index 00000000000..d959329b9fc --- /dev/null +++ b/src/test/ui/macros/format-args-temporaries-async.rs @@ -0,0 +1,37 @@ +// check-pass +// edition:2021 + +use std::fmt::{self, Display}; +use std::future::Future; +use std::io; +use std::pin::Pin; +use std::task::{Context, Poll}; + +struct AsyncStdout; + +impl AsyncStdout { + fn write_fmt<'a>(&'a mut self, _args: fmt::Arguments) -> WriteFmtFuture<'a, Self> + where + Self: Unpin, + { + WriteFmtFuture(self) + } +} + +struct WriteFmtFuture<'a, T>(&'a mut T); + +impl<'a, T> Future for WriteFmtFuture<'a, T> { + type Output = io::Result<()>; + fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> { + unimplemented!() + } +} + +async fn async_main() { + let _write = write!(&mut AsyncStdout, "...").await; + let _writeln = writeln!(&mut AsyncStdout, "...").await; +} + +fn main() { + let _ = async_main; +} diff --git a/src/test/ui/macros/format-args-temporaries-in-write.rs b/src/test/ui/macros/format-args-temporaries-in-write.rs new file mode 100644 index 00000000000..339ccbc33ac --- /dev/null +++ b/src/test/ui/macros/format-args-temporaries-in-write.rs @@ -0,0 +1,50 @@ +// check-fail + +use std::fmt::{self, Display}; + +struct Mutex; + +impl Mutex { + fn lock(&self) -> MutexGuard { + MutexGuard(self) + } +} + +struct MutexGuard<'a>(&'a Mutex); + +impl<'a> Drop for MutexGuard<'a> { + fn drop(&mut self) { + // Empty but this is a necessary part of the repro. Otherwise borrow + // checker is fine with 'a dangling at the time that MutexGuard goes out + // of scope. + } +} + +struct Out; + +impl Out { + fn write_fmt(&self, _args: fmt::Arguments) {} +} + +impl<'a> Display for MutexGuard<'a> { + fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result { + Ok(()) + } +} + +fn main() { + // FIXME(dtolnay): We actually want both of these to work. I think it's + // sadly unimplementable today though. + + let _write = { + let mutex = Mutex; + write!(Out, "{}", mutex.lock()) /* no semicolon */ + //~^ ERROR `mutex` does not live long enough + }; + + let _writeln = { + let mutex = Mutex; + writeln!(Out, "{}", mutex.lock()) /* no semicolon */ + //~^ ERROR `mutex` does not live long enough + }; +} diff --git a/src/test/ui/macros/format-args-temporaries-in-write.stderr b/src/test/ui/macros/format-args-temporaries-in-write.stderr new file mode 100644 index 00000000000..03ecc4b4418 --- /dev/null +++ b/src/test/ui/macros/format-args-temporaries-in-write.stderr @@ -0,0 +1,43 @@ +error[E0597]: `mutex` does not live long enough + --> $DIR/format-args-temporaries-in-write.rs:41:27 + | +LL | write!(Out, "{}", mutex.lock()) /* no semicolon */ + | ^^^^^^^^^^^^ + | | + | borrowed value does not live long enough + | a temporary with access to the borrow is created here ... +LL | +LL | }; + | -- ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `MutexGuard` + | | + | `mutex` dropped here while still borrowed + | +help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped + --> $SRC_DIR/core/src/macros/mod.rs:LL:COL + | +LL | $dst.write_fmt($crate::format_args!($($arg)*)); + | + + +error[E0597]: `mutex` does not live long enough + --> $DIR/format-args-temporaries-in-write.rs:47:29 + | +LL | writeln!(Out, "{}", mutex.lock()) /* no semicolon */ + | ^^^^^^^^^^^^ + | | + | borrowed value does not live long enough + | a temporary with access to the borrow is created here ... +LL | +LL | }; + | -- ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `MutexGuard` + | | + | `mutex` dropped here while still borrowed + | +help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped + --> $SRC_DIR/core/src/macros/mod.rs:LL:COL + | +LL | $dst.write_fmt($crate::format_args_nl!($($arg)*)); + | + + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/macros/format-args-temporaries.rs b/src/test/ui/macros/format-args-temporaries.rs index ddd4c9754bf..59323828bc3 100644 --- a/src/test/ui/macros/format-args-temporaries.rs +++ b/src/test/ui/macros/format-args-temporaries.rs @@ -20,10 +20,6 @@ impl<'a> Drop for MutexGuard<'a> { } } -impl<'a> MutexGuard<'a> { - fn write_fmt(&self, _args: fmt::Arguments) {} -} - impl<'a> Display for MutexGuard<'a> { fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result { Ok(()) @@ -31,18 +27,6 @@ impl<'a> Display for MutexGuard<'a> { } fn main() { - let _write = { - let out = Mutex; - let mutex = Mutex; - write!(out.lock(), "{}", mutex.lock()) /* no semicolon */ - }; - - let _writeln = { - let out = Mutex; - let mutex = Mutex; - writeln!(out.lock(), "{}", mutex.lock()) /* no semicolon */ - }; - let _print = { let mutex = Mutex; print!("{}", mutex.lock()) /* no semicolon */ diff --git a/src/test/ui/process/process-spawn-nonexistent.rs b/src/test/ui/process/process-spawn-nonexistent.rs index 70de7316a81..a513722639a 100644 --- a/src/test/ui/process/process-spawn-nonexistent.rs +++ b/src/test/ui/process/process-spawn-nonexistent.rs @@ -6,9 +6,11 @@ use std::io::ErrorKind; use std::process::Command; fn main() { - assert_eq!(Command::new("nonexistent") - .spawn() - .unwrap_err() - .kind(), - ErrorKind::NotFound); + let result = Command::new("nonexistent").spawn().unwrap_err().kind(); + + assert!(matches!( + result, + // Under WSL with appendWindowsPath=true, this fails with PermissionDenied + ErrorKind::NotFound | ErrorKind::PermissionDenied + )); } diff --git a/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr b/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr index 00c682b2193..d20b1cc6d85 100644 --- a/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr @@ -1,8 +1,10 @@ -error[E0275]: overflow evaluating the requirement `<fn() -> Foo {foo} as FnOnce<()>>::Output == fn() -> Foo {foo}` +error[E0275]: overflow evaluating the requirement `fn() -> Foo {foo}: Sized` --> $DIR/issue-53398-cyclic-types.rs:5:13 | LL | fn foo() -> Foo { | ^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_53398_cyclic_types`) error: aborting due to previous error |
