diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index b4ff3d66f3d5b..aa584713593b5 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -1,3 +1,4 @@ +use std::cell::OnceCell; use std::collections::VecDeque; use std::rc::Rc; @@ -197,8 +198,8 @@ pub struct RegionInferenceContext<'tcx> { /// Reverse of the SCC constraint graph -- i.e., an edge `A -> B` exists if /// `B: A`. This is used to compute the universal regions that are required - /// to outlive a given SCC. Computed lazily. - rev_scc_graph: Option, + /// to outlive a given SCC. + rev_scc_graph: OnceCell, /// The "R0 member of [R1..Rn]" constraints, indexed by SCC. member_constraints: Rc>, @@ -502,7 +503,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { constraint_graph, constraint_sccs, scc_annotations, - rev_scc_graph: None, + rev_scc_graph: OnceCell::new(), member_constraints, member_constraints_applied: Vec::new(), universe_causes, @@ -809,9 +810,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { member_constraint_index: NllMemberConstraintIndex, choice_regions: &[ty::RegionVid], ) { - // Lazily compute the reverse graph, we'll need it later. - self.compute_reverse_scc_graph(); - // Create a mutable vector of the options. We'll try to winnow // them down. let mut choice_regions: Vec = choice_regions.to_vec(); @@ -849,7 +847,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // R0`). Therefore, we need only keep an option `O` if `UB: O` // for all UB. let universal_region_relations = &self.universal_region_relations; - for ub in self.rev_scc_graph.as_ref().unwrap().upper_bounds(scc) { + for ub in self.reverse_scc_graph().upper_bounds(scc) { debug!(?ub); choice_regions.retain(|&o_r| universal_region_relations.outlives(ub, o_r)); } diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 25cbd579ea1cd..f0d72085c407c 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -215,9 +215,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // FIXME: We could probably compute the LUB if there is one. let scc = self.constraint_sccs.scc(vid); let upper_bounds: Vec<_> = self - .rev_scc_graph - .as_ref() - .unwrap() + .reverse_scc_graph() .upper_bounds(scc) .filter_map(|vid| self.definitions[vid].external_name) .filter(|r| !r.is_static()) diff --git a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs index 8e04791461b26..604265f894081 100644 --- a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs +++ b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs @@ -59,13 +59,10 @@ impl ReverseSccGraph { } impl RegionInferenceContext<'_> { - /// Compute the reverse SCC-based constraint graph (lazily). - pub(super) fn compute_reverse_scc_graph(&mut self) { - if self.rev_scc_graph.is_some() { - return; - } - - self.rev_scc_graph = - Some(ReverseSccGraph::compute(&self.constraint_sccs, self.universal_regions())); + /// Return the reverse graph of the region SCCs, initialising it if needed. + pub(super) fn reverse_scc_graph(&self) -> &ReverseSccGraph { + self.rev_scc_graph.get_or_init(|| { + ReverseSccGraph::compute(&self.constraint_sccs, self.universal_regions()) + }) } } diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index 211e2a92f73d8..c15d7d6f732c9 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -1,6 +1,7 @@ use std::{fmt, iter, mem}; use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx}; +use rustc_hir::def::DefKind; use rustc_hir::lang_items::LangItem; use rustc_index::Idx; use rustc_middle::mir::*; @@ -254,8 +255,19 @@ where // impl_item_refs may be empty if drop fn is not implemented in 'impl AsyncDrop for ...' // (#140974). // Such code will report error, so just generate sync drop here and return - let Some(drop_fn_def_id) = - tcx.associated_item_def_ids(drop_trait).into_iter().nth(0).copied() + let Some(drop_fn_def_id) = tcx + .associated_item_def_ids(drop_trait) + .first() + .and_then(|def_id| { + if tcx.def_kind(def_id) == DefKind::AssocFn + && tcx.check_args_compatible(*def_id, trait_args) + { + Some(def_id) + } else { + None + } + }) + .copied() else { tcx.dcx().span_delayed_bug( self.elaborator.body().span, diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index fb1534d0b2798..744e99c86e1a6 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -415,7 +415,7 @@ pub(crate) enum AliasPossibility { } #[derive(Copy, Clone, Debug)] -pub(crate) enum PathSource<'a> { +pub(crate) enum PathSource<'a, 'c> { /// Type paths `Path`. Type, /// Trait paths in bounds or impls. @@ -429,7 +429,10 @@ pub(crate) enum PathSource<'a> { /// Paths in tuple struct patterns `Path(..)`. TupleStruct(Span, &'a [Span]), /// `m::A::B` in `::B::C`. - TraitItem(Namespace), + /// + /// Second field holds the "cause" of this one, i.e. the context within + /// which the trait item is resolved. Used for diagnostics. + TraitItem(Namespace, &'c PathSource<'a, 'c>), /// Paths in delegation item Delegation, /// An arg in a `use<'a, N>` precise-capturing bound. @@ -440,7 +443,7 @@ pub(crate) enum PathSource<'a> { DefineOpaques, } -impl<'a> PathSource<'a> { +impl<'a> PathSource<'a, '_> { fn namespace(self) -> Namespace { match self { PathSource::Type @@ -452,7 +455,7 @@ impl<'a> PathSource<'a> { | PathSource::TupleStruct(..) | PathSource::Delegation | PathSource::ReturnTypeNotation => ValueNS, - PathSource::TraitItem(ns) => ns, + PathSource::TraitItem(ns, _) => ns, PathSource::PreciseCapturingArg(ns) => ns, } } @@ -480,8 +483,9 @@ impl<'a> PathSource<'a> { PathSource::Trait(_) => "trait", PathSource::Pat => "unit struct, unit variant or constant", PathSource::Struct => "struct, variant or union type", - PathSource::TupleStruct(..) => "tuple struct or tuple variant", - PathSource::TraitItem(ns) => match ns { + PathSource::TraitItem(ValueNS, PathSource::TupleStruct(..)) + | PathSource::TupleStruct(..) => "tuple struct or tuple variant", + PathSource::TraitItem(ns, _) => match ns { TypeNS => "associated type", ValueNS => "method or associated constant", MacroNS => bug!("associated macro"), @@ -585,7 +589,7 @@ impl<'a> PathSource<'a> { ) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } ), - PathSource::TraitItem(ns) => match res { + PathSource::TraitItem(ns, _) => match res { Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) if ns == ValueNS => true, Res::Def(DefKind::AssocTy, _) if ns == TypeNS => true, _ => false, @@ -2007,7 +2011,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { &mut self, partial_res: PartialRes, path: &[Segment], - source: PathSource<'_>, + source: PathSource<'_, '_>, path_span: Span, ) { let proj_start = path.len() - partial_res.unresolved_segments(); @@ -4206,7 +4210,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { id: NodeId, qself: &Option>, path: &Path, - source: PathSource<'ast>, + source: PathSource<'ast, '_>, ) { self.smart_resolve_path_fragment( qself, @@ -4223,7 +4227,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { &mut self, qself: &Option>, path: &[Segment], - source: PathSource<'ast>, + source: PathSource<'ast, '_>, finalize: Finalize, record_partial_res: RecordPartialRes, parent_qself: Option<&QSelf>, @@ -4404,6 +4408,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { path_span, source.defer_to_typeck(), finalize, + source, ) { Ok(Some(partial_res)) if let Some(res) = partial_res.full_res() => { // if we also have an associated type that matches the ident, stash a suggestion @@ -4526,12 +4531,13 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { span: Span, defer_to_typeck: bool, finalize: Finalize, + source: PathSource<'ast, '_>, ) -> Result, Spanned>> { let mut fin_res = None; for (i, &ns) in [primary_ns, TypeNS, ValueNS].iter().enumerate() { if i == 0 || ns != primary_ns { - match self.resolve_qpath(qself, path, ns, finalize)? { + match self.resolve_qpath(qself, path, ns, finalize, source)? { Some(partial_res) if partial_res.unresolved_segments() == 0 || defer_to_typeck => { @@ -4568,6 +4574,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { path: &[Segment], ns: Namespace, finalize: Finalize, + source: PathSource<'ast, '_>, ) -> Result, Spanned>> { debug!( "resolve_qpath(qself={:?}, path={:?}, ns={:?}, finalize={:?})", @@ -4615,7 +4622,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let partial_res = self.smart_resolve_path_fragment( &None, &path[..=qself.position], - PathSource::TraitItem(ns), + PathSource::TraitItem(ns, &source), Finalize::with_root_span(finalize.node_id, finalize.path_span, qself.path_span), RecordPartialRes::No, Some(&qself), diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index ca25cdc9563d9..97a45fcf23303 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -175,7 +175,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { &mut self, path: &[Segment], span: Span, - source: PathSource<'_>, + source: PathSource<'_, '_>, res: Option, ) -> BaseError { // Make the base error. @@ -421,7 +421,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { path: &[Segment], following_seg: Option<&Segment>, span: Span, - source: PathSource<'_>, + source: PathSource<'_, '_>, res: Option, qself: Option<&QSelf>, ) -> (Diag<'tcx>, Vec) { @@ -539,12 +539,12 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { path: &[Segment], following_seg: Option<&Segment>, span: Span, - source: PathSource<'_>, + source: PathSource<'_, '_>, res: Option, qself: Option<&QSelf>, ) { if let Some(Res::Def(DefKind::AssocFn, _)) = res - && let PathSource::TraitItem(TypeNS) = source + && let PathSource::TraitItem(TypeNS, _) = source && let None = following_seg && let Some(qself) = qself && let TyKind::Path(None, ty_path) = &qself.ty.kind @@ -650,7 +650,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn try_lookup_name_relaxed( &mut self, err: &mut Diag<'_>, - source: PathSource<'_>, + source: PathSource<'_, '_>, path: &[Segment], following_seg: Option<&Segment>, span: Span, @@ -940,7 +940,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn suggest_trait_and_bounds( &mut self, err: &mut Diag<'_>, - source: PathSource<'_>, + source: PathSource<'_, '_>, res: Option, span: Span, base_error: &BaseError, @@ -1017,7 +1017,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn suggest_typo( &mut self, err: &mut Diag<'_>, - source: PathSource<'_>, + source: PathSource<'_, '_>, path: &[Segment], following_seg: Option<&Segment>, span: Span, @@ -1063,7 +1063,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn suggest_shadowed( &mut self, err: &mut Diag<'_>, - source: PathSource<'_>, + source: PathSource<'_, '_>, path: &[Segment], following_seg: Option<&Segment>, span: Span, @@ -1096,7 +1096,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn err_code_special_cases( &mut self, err: &mut Diag<'_>, - source: PathSource<'_>, + source: PathSource<'_, '_>, path: &[Segment], span: Span, ) { @@ -1141,7 +1141,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn suggest_self_ty( &mut self, err: &mut Diag<'_>, - source: PathSource<'_>, + source: PathSource<'_, '_>, path: &[Segment], span: Span, ) -> bool { @@ -1164,7 +1164,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn suggest_self_value( &mut self, err: &mut Diag<'_>, - source: PathSource<'_>, + source: PathSource<'_, '_>, path: &[Segment], span: Span, ) -> bool { @@ -1332,7 +1332,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn suggest_swapping_misplaced_self_ty_and_trait( &mut self, err: &mut Diag<'_>, - source: PathSource<'_>, + source: PathSource<'_, '_>, res: Option, span: Span, ) { @@ -1361,7 +1361,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { &mut self, err: &mut Diag<'_>, res: Option, - source: PathSource<'_>, + source: PathSource<'_, '_>, ) { let PathSource::TupleStruct(_, _) = source else { return }; let Some(Res::Def(DefKind::Fn, _)) = res else { return }; @@ -1373,7 +1373,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { &mut self, err: &mut Diag<'_>, res: Option, - source: PathSource<'_>, + source: PathSource<'_, '_>, span: Span, ) { let PathSource::Trait(_) = source else { return }; @@ -1422,7 +1422,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn suggest_pattern_match_with_let( &mut self, err: &mut Diag<'_>, - source: PathSource<'_>, + source: PathSource<'_, '_>, span: Span, ) -> bool { if let PathSource::Expr(_) = source @@ -1448,10 +1448,10 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn get_single_associated_item( &mut self, path: &[Segment], - source: &PathSource<'_>, + source: &PathSource<'_, '_>, filter_fn: &impl Fn(Res) -> bool, ) -> Option { - if let crate::PathSource::TraitItem(_) = source { + if let crate::PathSource::TraitItem(_, _) = source { let mod_path = &path[..path.len() - 1]; if let PathResult::Module(ModuleOrUniformRoot::Module(module)) = self.resolve_path(mod_path, None, None) @@ -1556,7 +1556,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { /// Check if the source is call expression and the first argument is `self`. If true, /// return the span of whole call and the span for all arguments expect the first one (`self`). - fn call_has_self_arg(&self, source: PathSource<'_>) -> Option<(Span, Option)> { + fn call_has_self_arg(&self, source: PathSource<'_, '_>) -> Option<(Span, Option)> { let mut has_self_arg = None; if let PathSource::Expr(Some(parent)) = source && let ExprKind::Call(_, args) = &parent.kind @@ -1614,7 +1614,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { &mut self, err: &mut Diag<'_>, span: Span, - source: PathSource<'_>, + source: PathSource<'_, '_>, path: &[Segment], res: Res, path_str: &str, @@ -1666,7 +1666,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } }; - let find_span = |source: &PathSource<'_>, err: &mut Diag<'_>| { + let find_span = |source: &PathSource<'_, '_>, err: &mut Diag<'_>| { match source { PathSource::Expr(Some(Expr { span, kind: ExprKind::Call(_, _), .. })) | PathSource::TupleStruct(span, _) => { @@ -2050,8 +2050,86 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { err.span_label(span, fallback_label.to_string()); err.note("can't use `Self` as a constructor, you must use the implemented struct"); } - (Res::Def(DefKind::TyAlias | DefKind::AssocTy, _), _) if ns == ValueNS => { + ( + Res::Def(DefKind::TyAlias | DefKind::AssocTy, _), + PathSource::TraitItem(ValueNS, PathSource::TupleStruct(whole, args)), + ) => { + err.note("can't use a type alias as tuple pattern"); + + let mut suggestion = Vec::new(); + + if let &&[first, ..] = args + && let &&[.., last] = args + { + suggestion.extend([ + // "0: " has to be included here so that the fix is machine applicable. + // + // If this would only add " { " and then the code below add "0: ", + // rustfix would crash, because end of this suggestion is the same as start + // of the suggestion below. Thus, we have to merge these... + (span.between(first), " { 0: ".to_owned()), + (last.between(whole.shrink_to_hi()), " }".to_owned()), + ]); + + suggestion.extend( + args.iter() + .enumerate() + .skip(1) // See above + .map(|(index, &arg)| (arg.shrink_to_lo(), format!("{index}: "))), + ) + } else { + suggestion.push((span.between(whole.shrink_to_hi()), " {}".to_owned())); + } + + err.multipart_suggestion( + "use struct pattern instead", + suggestion, + Applicability::MachineApplicable, + ); + } + ( + Res::Def(DefKind::TyAlias | DefKind::AssocTy, _), + PathSource::TraitItem( + ValueNS, + PathSource::Expr(Some(ast::Expr { + span: whole, + kind: ast::ExprKind::Call(_, args), + .. + })), + ), + ) => { err.note("can't use a type alias as a constructor"); + + let mut suggestion = Vec::new(); + + if let [first, ..] = &**args + && let [.., last] = &**args + { + suggestion.extend([ + // "0: " has to be included here so that the fix is machine applicable. + // + // If this would only add " { " and then the code below add "0: ", + // rustfix would crash, because end of this suggestion is the same as start + // of the suggestion below. Thus, we have to merge these... + (span.between(first.span), " { 0: ".to_owned()), + (last.span.between(whole.shrink_to_hi()), " }".to_owned()), + ]); + + suggestion.extend( + args.iter() + .enumerate() + .skip(1) // See above + .map(|(index, arg)| (arg.span.shrink_to_lo(), format!("{index}: "))), + ) + } else { + suggestion.push((span.between(whole.shrink_to_hi()), " {}".to_owned())); + } + + err.multipart_suggestion( + "use struct expression instead", + suggestion, + Applicability::MachineApplicable, + ); } _ => return false, } @@ -2621,7 +2699,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn suggest_using_enum_variant( &mut self, err: &mut Diag<'_>, - source: PathSource<'_>, + source: PathSource<'_, '_>, def_id: DefId, span: Span, ) { @@ -2799,7 +2877,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { pub(crate) fn suggest_adding_generic_parameter( &self, path: &[Segment], - source: PathSource<'_>, + source: PathSource<'_, '_>, ) -> Option<(Span, &'static str, String, Applicability)> { let (ident, span) = match path { [segment] diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index 01bb1324645be..fa839d2748d86 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -12,10 +12,14 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::unord::UnordSet; use rustc_middle::ty::TyCtxt; use rustc_span::def_id::DefId; +use rustc_span::source_map::SourceMap; use rustc_span::{DUMMY_SP, InnerSpan, Span, Symbol, sym}; use thin_vec::ThinVec; use tracing::{debug, trace}; +#[cfg(test)] +mod tests; + #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum DocFragmentKind { /// A doc fragment created from a `///` or `//!` doc comment. @@ -531,10 +535,20 @@ pub fn source_span_for_markdown_range( markdown: &str, md_range: &Range, fragments: &[DocFragment], +) -> Option { + let map = tcx.sess.source_map(); + source_span_for_markdown_range_inner(map, markdown, md_range, fragments) +} + +// inner function used for unit testing +pub fn source_span_for_markdown_range_inner( + map: &SourceMap, + markdown: &str, + md_range: &Range, + fragments: &[DocFragment], ) -> Option { use rustc_span::BytePos; - let map = tcx.sess.source_map(); if let &[fragment] = &fragments && fragment.kind == DocFragmentKind::RawDoc && let Ok(snippet) = map.span_to_snippet(fragment.span) @@ -570,7 +584,13 @@ pub fn source_span_for_markdown_range( { // If there is either a match in a previous fragment, or // multiple matches in this fragment, there is ambiguity. - if match_data.is_none() && !snippet[match_start + 1..].contains(pat) { + // the snippet cannot be zero-sized, because it matches + // the pattern, which is checked to not be zero sized. + if match_data.is_none() + && !snippet.as_bytes()[match_start + 1..] + .windows(pat.len()) + .any(|s| s == pat.as_bytes()) + { match_data = Some((i, match_start)); } else { // Heirustic produced ambiguity, return nothing. diff --git a/compiler/rustc_resolve/src/rustdoc/tests.rs b/compiler/rustc_resolve/src/rustdoc/tests.rs new file mode 100644 index 0000000000000..221ac907e7c9c --- /dev/null +++ b/compiler/rustc_resolve/src/rustdoc/tests.rs @@ -0,0 +1,50 @@ +use std::path::PathBuf; + +use rustc_span::source_map::{FilePathMapping, SourceMap}; +use rustc_span::symbol::sym; +use rustc_span::{BytePos, Span}; + +use super::{DocFragment, DocFragmentKind, source_span_for_markdown_range_inner}; + +#[test] +fn single_backtick() { + let sm = SourceMap::new(FilePathMapping::empty()); + sm.new_source_file(PathBuf::from("foo.rs").into(), r#"#[doc = "`"] fn foo() {}"#.to_string()); + let span = source_span_for_markdown_range_inner( + &sm, + "`", + &(0..1), + &[DocFragment { + span: Span::with_root_ctxt(BytePos(8), BytePos(11)), + item_id: None, + kind: DocFragmentKind::RawDoc, + doc: sym::empty, // unused placeholder + indent: 0, + }], + ) + .unwrap(); + assert_eq!(span.lo(), BytePos(9)); + assert_eq!(span.hi(), BytePos(10)); +} + +#[test] +fn utf8() { + // regression test for https://github.com/rust-lang/rust/issues/141665 + let sm = SourceMap::new(FilePathMapping::empty()); + sm.new_source_file(PathBuf::from("foo.rs").into(), r#"#[doc = "⚠"] fn foo() {}"#.to_string()); + let span = source_span_for_markdown_range_inner( + &sm, + "⚠", + &(0..3), + &[DocFragment { + span: Span::with_root_ctxt(BytePos(8), BytePos(14)), + item_id: None, + kind: DocFragmentKind::RawDoc, + doc: sym::empty, // unused placeholder + indent: 0, + }], + ) + .unwrap(); + assert_eq!(span.lo(), BytePos(9)); + assert_eq!(span.hi(), BytePos(12)); +} diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index 92f1bd8ab7367..0e711890e076f 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -172,6 +172,11 @@ fn current_dll_path() -> Result { Ok(OsString::from_wide(&filename).into()) } +#[cfg(target_os = "wasi")] +fn current_dll_path() -> Result { + Err("current_dll_path is not supported on WASI".to_string()) +} + pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> { let target = crate::config::host_tuple(); let mut sysroot_candidates: SmallVec<[PathBuf; 2]> = smallvec![get_or_default_sysroot()]; diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index bb2bf128be1f6..595cc1fe025ec 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -207,7 +207,7 @@ impl CStr { /// * `ptr` must be [valid] for reads of bytes up to and including the nul terminator. /// This means in particular: /// - /// * The entire memory range of this `CStr` must be contained within a single allocated object! + /// * The entire memory range of this `CStr` must be contained within a single allocation! /// * `ptr` must be non-null even for a zero-length cstr. /// /// * The memory referenced by the returned `CStr` must not be mutated for diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 102607a19801d..d147cf889cc03 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -1723,7 +1723,7 @@ pub const fn needs_drop() -> bool; /// # Safety /// /// If the computed offset is non-zero, then both the starting and resulting pointer must be -/// either in bounds or at the end of an allocated object. If either pointer is out +/// either in bounds or at the end of an allocation. If either pointer is out /// of bounds or arithmetic overflow occurs then this operation is undefined behavior. /// /// The stabilized version of this intrinsic is [`pointer::offset`]. diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 17c4b48836134..10b11613f90fa 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1623,7 +1623,7 @@ mod prim_usize {} /// * if `size_of_val(t) > 0`, then `t` is dereferenceable for `size_of_val(t)` many bytes /// /// If `t` points at address `a`, being "dereferenceable" for N bytes means that the memory range -/// `[a, a + N)` is all contained within a single [allocated object]. +/// `[a, a + N)` is all contained within a single [allocation]. /// /// For instance, this means that unsafe code in a safe function may assume these invariants are /// ensured of arguments passed by the caller, and it may assume that these invariants are ensured @@ -1639,7 +1639,7 @@ mod prim_usize {} /// may be unsound or become unsound in future versions of Rust depending on how this question is /// decided. /// -/// [allocated object]: ptr#allocated-object +/// [allocation]: ptr#allocation #[stable(feature = "rust1", since = "1.0.0")] mod prim_ref {} diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index f94737138dcaa..a1dab23ea7b49 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -482,17 +482,17 @@ impl *const T { /// /// This operation itself is always safe, but using the resulting pointer is not. /// - /// The resulting pointer "remembers" the [allocated object] that `self` points to + /// The resulting pointer "remembers" the [allocation] that `self` points to /// (this is called "[Provenance](ptr/index.html#provenance)"). - /// The pointer must not be used to read or write other allocated objects. + /// The pointer must not be used to read or write other allocations. /// /// In other words, `let z = x.wrapping_offset((y as isize) - (x as isize))` does *not* make `z` /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still /// attached to the object `x` is attached to, and dereferencing it is Undefined Behavior unless - /// `x` and `y` point into the same allocated object. + /// `x` and `y` point into the same allocation. /// /// Compared to [`offset`], this method basically delays the requirement of staying within the - /// same allocated object: [`offset`] is immediate Undefined Behavior when crossing object + /// same allocation: [`offset`] is immediate Undefined Behavior when crossing object /// boundaries; `wrapping_offset` produces a pointer but still leads to Undefined Behavior if a /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`offset`] /// can be optimized better and is thus preferable in performance-sensitive code. @@ -500,10 +500,10 @@ impl *const T { /// The delayed check only considers the value of the pointer that was dereferenced, not the /// intermediate values used during the computation of the final result. For example, /// `x.wrapping_offset(o).wrapping_offset(o.wrapping_neg())` is always the same as `x`. In other - /// words, leaving the allocated object and then re-entering it later is permitted. + /// words, leaving the allocation and then re-entering it later is permitted. /// /// [`offset`]: #method.offset - /// [allocated object]: crate::ptr#allocated-object + /// [allocation]: crate::ptr#allocation /// /// # Examples /// @@ -616,7 +616,7 @@ impl *const T { /// * `self` and `origin` must either /// /// * point to the same address, or - /// * both be [derived from][crate::ptr#provenance] a pointer to the same [allocated object], and the memory range between + /// * both be [derived from][crate::ptr#provenance] a pointer to the same [allocation], and the memory range between /// the two pointers must be in bounds of that object. (See below for an example.) /// /// * The distance between the pointers, in bytes, must be an exact multiple @@ -624,10 +624,10 @@ impl *const T { /// /// As a consequence, the absolute distance between the pointers, in bytes, computed on /// mathematical integers (without "wrapping around"), cannot overflow an `isize`. This is - /// implied by the in-bounds requirement, and the fact that no allocated object can be larger + /// implied by the in-bounds requirement, and the fact that no allocation can be larger /// than `isize::MAX` bytes. /// - /// The requirement for pointers to be derived from the same allocated object is primarily + /// The requirement for pointers to be derived from the same allocation is primarily /// needed for `const`-compatibility: the distance between pointers into *different* allocated /// objects is not known at compile-time. However, the requirement also exists at /// runtime and may be exploited by optimizations. If you wish to compute the difference between @@ -636,7 +636,7 @@ impl *const T { // FIXME: recommend `addr()` instead of `as usize` once that is stable. /// /// [`add`]: #method.add - /// [allocated object]: crate::ptr#allocated-object + /// [allocation]: crate::ptr#allocation /// /// # Panics /// @@ -969,12 +969,12 @@ impl *const T { /// "wrapping around"), must fit in an `isize`. /// /// * If the computed offset is non-zero, then `self` must be [derived from][crate::ptr#provenance] a pointer to some - /// [allocated object], and the entire memory range between `self` and the result must be in - /// bounds of that allocated object. In particular, this range must not "wrap around" the edge + /// [allocation], and the entire memory range between `self` and the result must be in + /// bounds of that allocation. In particular, this range must not "wrap around" the edge /// of the address space. /// - /// Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset - /// stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement. + /// Allocations can never be larger than `isize::MAX` bytes, so if the computed offset + /// stays in bounds of the allocation, it is guaranteed to satisfy the first requirement. /// This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec`) is always /// safe. /// @@ -983,7 +983,7 @@ impl *const T { /// enables more aggressive compiler optimizations. /// /// [`wrapping_sub`]: #method.wrapping_sub - /// [allocated object]: crate::ptr#allocated-object + /// [allocation]: crate::ptr#allocation /// /// # Examples /// @@ -1073,16 +1073,16 @@ impl *const T { /// /// This operation itself is always safe, but using the resulting pointer is not. /// - /// The resulting pointer "remembers" the [allocated object] that `self` points to; it must not - /// be used to read or write other allocated objects. + /// The resulting pointer "remembers" the [allocation] that `self` points to; it must not + /// be used to read or write other allocations. /// /// In other words, `let z = x.wrapping_add((y as usize) - (x as usize))` does *not* make `z` /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still /// attached to the object `x` is attached to, and dereferencing it is Undefined Behavior unless - /// `x` and `y` point into the same allocated object. + /// `x` and `y` point into the same allocation. /// /// Compared to [`add`], this method basically delays the requirement of staying within the - /// same allocated object: [`add`] is immediate Undefined Behavior when crossing object + /// same allocation: [`add`] is immediate Undefined Behavior when crossing object /// boundaries; `wrapping_add` produces a pointer but still leads to Undefined Behavior if a /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`add`] /// can be optimized better and is thus preferable in performance-sensitive code. @@ -1090,10 +1090,10 @@ impl *const T { /// The delayed check only considers the value of the pointer that was dereferenced, not the /// intermediate values used during the computation of the final result. For example, /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the - /// allocated object and then re-entering it later is permitted. + /// allocation and then re-entering it later is permitted. /// /// [`add`]: #method.add - /// [allocated object]: crate::ptr#allocated-object + /// [allocation]: crate::ptr#allocation /// /// # Examples /// @@ -1152,16 +1152,16 @@ impl *const T { /// /// This operation itself is always safe, but using the resulting pointer is not. /// - /// The resulting pointer "remembers" the [allocated object] that `self` points to; it must not - /// be used to read or write other allocated objects. + /// The resulting pointer "remembers" the [allocation] that `self` points to; it must not + /// be used to read or write other allocations. /// /// In other words, `let z = x.wrapping_sub((x as usize) - (y as usize))` does *not* make `z` /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still /// attached to the object `x` is attached to, and dereferencing it is Undefined Behavior unless - /// `x` and `y` point into the same allocated object. + /// `x` and `y` point into the same allocation. /// /// Compared to [`sub`], this method basically delays the requirement of staying within the - /// same allocated object: [`sub`] is immediate Undefined Behavior when crossing object + /// same allocation: [`sub`] is immediate Undefined Behavior when crossing object /// boundaries; `wrapping_sub` produces a pointer but still leads to Undefined Behavior if a /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`sub`] /// can be optimized better and is thus preferable in performance-sensitive code. @@ -1169,10 +1169,10 @@ impl *const T { /// The delayed check only considers the value of the pointer that was dereferenced, not the /// intermediate values used during the computation of the final result. For example, /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the - /// allocated object and then re-entering it later is permitted. + /// allocation and then re-entering it later is permitted. /// /// [`sub`]: #method.sub - /// [allocated object]: crate::ptr#allocated-object + /// [allocation]: crate::ptr#allocation /// /// # Examples /// @@ -1564,8 +1564,8 @@ impl *const [T] { /// * The pointer must be [valid] for reads for `ptr.len() * size_of::()` many bytes, /// and it must be properly aligned. This means in particular: /// - /// * The entire memory range of this slice must be contained within a single [allocated object]! - /// Slices can never span across multiple allocated objects. + /// * The entire memory range of this slice must be contained within a single [allocation]! + /// Slices can never span across multiple allocations. /// /// * The pointer must be aligned even for zero-length slices. One /// reason for this is that enum layout optimizations may rely on references @@ -1586,7 +1586,7 @@ impl *const [T] { /// See also [`slice::from_raw_parts`][]. /// /// [valid]: crate::ptr#safety - /// [allocated object]: crate::ptr#allocated-object + /// [allocation]: crate::ptr#allocation /// /// # Panics during const evaluation /// diff --git a/library/core/src/ptr/docs/add.md b/library/core/src/ptr/docs/add.md index 555dc11c1bb40..ae7c7785684c9 100644 --- a/library/core/src/ptr/docs/add.md +++ b/library/core/src/ptr/docs/add.md @@ -15,12 +15,12 @@ If any of the following conditions are violated, the result is Undefined Behavio "wrapping around"), must fit in an `isize`. * If the computed offset is non-zero, then `self` must be [derived from][crate::ptr#provenance] a pointer to some -[allocated object], and the entire memory range between `self` and the result must be in -bounds of that allocated object. In particular, this range must not "wrap around" the edge +[allocation], and the entire memory range between `self` and the result must be in +bounds of that allocation. In particular, this range must not "wrap around" the edge of the address space. Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset -stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement. +stays in bounds of the allocation, it is guaranteed to satisfy the first requirement. This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec`) is always safe. @@ -29,4 +29,4 @@ difficult to satisfy. The only advantage of this method is that it enables more aggressive compiler optimizations. [`wrapping_add`]: #method.wrapping_add -[allocated object]: crate::ptr#allocated-object +[allocation]: crate::ptr#allocation diff --git a/library/core/src/ptr/docs/offset.md b/library/core/src/ptr/docs/offset.md index 6e431e054b052..f2e335a79a5c2 100644 --- a/library/core/src/ptr/docs/offset.md +++ b/library/core/src/ptr/docs/offset.md @@ -11,13 +11,13 @@ If any of the following conditions are violated, the result is Undefined Behavio "wrapping around"), must fit in an `isize`. * If the computed offset is non-zero, then `self` must be [derived from][crate::ptr#provenance] a pointer to some -[allocated object], and the entire memory range between `self` and the result must be in -bounds of that allocated object. In particular, this range must not "wrap around" the edge +[allocation], and the entire memory range between `self` and the result must be in +bounds of that allocation. In particular, this range must not "wrap around" the edge of the address space. Note that "range" here refers to a half-open range as usual in Rust, i.e., `self..result` for non-negative offsets and `result..self` for negative offsets. Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset -stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement. +stays in bounds of the allocation, it is guaranteed to satisfy the first requirement. This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec`) is always safe. @@ -26,4 +26,4 @@ difficult to satisfy. The only advantage of this method is that it enables more aggressive compiler optimizations. [`wrapping_offset`]: #method.wrapping_offset -[allocated object]: crate::ptr#allocated-object +[allocation]: crate::ptr#allocation diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 99c4211cea862..81bf6778b05db 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -19,10 +19,10 @@ //! pointer. The following points are only concerned with non-zero-sized accesses. //! * A [null] pointer is *never* valid. //! * For a pointer to be valid, it is necessary, but not always sufficient, that the pointer be -//! *dereferenceable*. The [provenance] of the pointer is used to determine which [allocated -//! object] it is derived from; a pointer is dereferenceable if the memory range of the given size -//! starting at the pointer is entirely contained within the bounds of that allocated object. Note -//! that in Rust, every (stack-allocated) variable is considered a separate allocated object. +//! *dereferenceable*. The [provenance] of the pointer is used to determine which [allocation] +//! it is derived from; a pointer is dereferenceable if the memory range of the given size +//! starting at the pointer is entirely contained within the bounds of that allocation. Note +//! that in Rust, every (stack-allocated) variable is considered a separate allocation. //! * All accesses performed by functions in this module are *non-atomic* in the sense //! of [atomic operations] used to synchronize between threads. This means it is //! undefined behavior to perform two concurrent accesses to the same location from different @@ -30,7 +30,7 @@ //! includes [`read_volatile`] and [`write_volatile`]: Volatile accesses cannot //! be used for inter-thread synchronization. //! * The result of casting a reference to a pointer is valid for as long as the -//! underlying object is live and no reference (just raw pointers) is used to +//! underlying allocation is live and no reference (just raw pointers) is used to //! access the same memory. That is, reference and pointer accesses cannot be //! interleaved. //! @@ -95,24 +95,26 @@ //! //! [valid value]: ../../reference/behavior-considered-undefined.html#invalid-values //! -//! ## Allocated object +//! ## Allocation //! -//! An *allocated object* is a subset of program memory which is addressable +//! +//! +//! An *allocation* is a subset of program memory which is addressable //! from Rust, and within which pointer arithmetic is possible. Examples of -//! allocated objects include heap allocations, stack-allocated variables, +//! allocations include heap allocations, stack-allocated variables, //! statics, and consts. The safety preconditions of some Rust operations - //! such as `offset` and field projections (`expr.field`) - are defined in -//! terms of the allocated objects on which they operate. +//! terms of the allocations on which they operate. //! -//! An allocated object has a base address, a size, and a set of memory -//! addresses. It is possible for an allocated object to have zero size, but -//! such an allocated object will still have a base address. The base address -//! of an allocated object is not necessarily unique. While it is currently the -//! case that an allocated object always has a set of memory addresses which is +//! An allocation has a base address, a size, and a set of memory +//! addresses. It is possible for an allocation to have zero size, but +//! such an allocation will still have a base address. The base address +//! of an allocation is not necessarily unique. While it is currently the +//! case that an allocation always has a set of memory addresses which is //! fully contiguous (i.e., has no "holes"), there is no guarantee that this //! will not change in the future. //! -//! For any allocated object with `base` address, `size`, and a set of +//! For any allocation with `base` address, `size`, and a set of //! `addresses`, the following are guaranteed: //! - For all addresses `a` in `addresses`, `a` is in the range `base .. (base + //! size)` (note that this requires `a < base + size`, not `a <= base + size`) @@ -122,11 +124,11 @@ //! - `size <= isize::MAX` //! //! As a consequence of these guarantees, given any address `a` within the set -//! of addresses of an allocated object: +//! of addresses of an allocation: //! - It is guaranteed that `a - base` does not overflow `isize` //! - It is guaranteed that `a - base` is non-negative //! - It is guaranteed that, given `o = a - base` (i.e., the offset of `a` within -//! the allocated object), `base + o` will not wrap around the address space (in +//! the allocation), `base + o` will not wrap around the address space (in //! other words, will not overflow `usize`) //! //! [`null()`]: null @@ -138,8 +140,8 @@ //! and the freed memory gets reallocated before your read/write (in fact this is the //! worst-case scenario, UAFs would be much less concerning if this didn't happen!). //! As another example, consider that [`wrapping_offset`] is documented to "remember" -//! the allocated object that the original pointer points to, even if it is offset far -//! outside the memory range occupied by that allocated object. +//! the allocation that the original pointer points to, even if it is offset far +//! outside the memory range occupied by that allocation. //! To rationalize claims like this, pointers need to somehow be *more* than just their addresses: //! they must have **provenance**. //! @@ -159,12 +161,12 @@ //! writes. Note that this can interact with the other components, e.g. a pointer might permit //! mutation only for a subset of addresses, or only for a subset of its maximal timespan. //! -//! When an [allocated object] is created, it has a unique Original Pointer. For alloc +//! When an [allocation] is created, it has a unique Original Pointer. For alloc //! APIs this is literally the pointer the call returns, and for local variables and statics, //! this is the name of the variable/static. (This is mildly overloading the term "pointer" //! for the sake of brevity/exposition.) //! -//! The Original Pointer for an allocated object has provenance that constrains the *spatial* +//! The Original Pointer for an allocation has provenance that constrains the *spatial* //! permissions of this pointer to the memory range of the allocation, and the *temporal* //! permissions to the lifetime of the allocation. Provenance is implicitly inherited by all //! pointers transitively derived from the Original Pointer through operations like [`offset`], @@ -192,10 +194,10 @@ //! provenance since they access an empty range of memory. //! //! * It is undefined behavior to [`offset`] a pointer across a memory range that is not contained -//! in the allocated object it is derived from, or to [`offset_from`] two pointers not derived -//! from the same allocated object. Provenance is used to say what exactly "derived from" even +//! in the allocation it is derived from, or to [`offset_from`] two pointers not derived +//! from the same allocation. Provenance is used to say what exactly "derived from" even //! means: the lineage of a pointer is traced back to the Original Pointer it descends from, and -//! that identifies the relevant allocated object. In particular, it's always UB to offset a +//! that identifies the relevant allocation. In particular, it's always UB to offset a //! pointer derived from something that is now deallocated, except if the offset is 0. //! //! But it *is* still sound to: @@ -216,7 +218,7 @@ //! * Compare arbitrary pointers by address. Pointer comparison ignores provenance and addresses //! *are* just integers, so there is always a coherent answer, even if the pointers are dangling //! or from different provenances. Note that if you get "lucky" and notice that a pointer at the -//! end of one allocated object is the "same" address as the start of another allocated object, +//! end of one allocation is the "same" address as the start of another allocation, //! anything you do with that fact is *probably* going to be gibberish. The scope of that //! gibberish is kept under control by the fact that the two pointers *still* aren't allowed to //! access the other's allocation (bytes), because they still have different provenance. @@ -369,7 +371,7 @@ //! integer-to-pointer casts. //! //! [aliasing]: ../../nomicon/aliasing.html -//! [allocated object]: #allocated-object +//! [allocation]: #allocation //! [provenance]: #provenance //! [book]: ../../book/ch19-01-unsafe-rust.html#dereferencing-a-raw-pointer //! [ub]: ../../reference/behavior-considered-undefined.html @@ -1289,7 +1291,7 @@ pub const unsafe fn swap(x: *mut T, y: *mut T) { // SAFETY: the caller must guarantee that `x` and `y` are // valid for writes and properly aligned. `tmp` cannot be // overlapping either `x` or `y` because `tmp` was just allocated - // on the stack as a separate allocated object. + // on the stack as a separate allocation. unsafe { copy_nonoverlapping(x, tmp.as_mut_ptr(), 1); copy(y, x, 1); // `x` and `y` may overlap @@ -1409,7 +1411,7 @@ pub const unsafe fn swap_nonoverlapping(x: *mut T, y: *mut T, count: usize) { // Going though a slice here helps codegen know the size fits in `isize` let slice = slice_from_raw_parts_mut(x, count); // SAFETY: This is all readable from the pointer, meaning it's one - // allocated object, and thus cannot be more than isize::MAX bytes. + // allocation, and thus cannot be more than isize::MAX bytes. let bytes = unsafe { mem::size_of_val_raw::<[T]>(slice) }; if let Some(bytes) = NonZero::new(bytes) { // SAFETY: These are the same ranges, just expressed in a different @@ -1563,7 +1565,7 @@ pub const unsafe fn replace(dst: *mut T, src: T) -> T { // SAFETY: the caller must guarantee that `dst` is valid to be // cast to a mutable reference (valid for writes, aligned, initialized), // and cannot overlap `src` since `dst` must point to a distinct - // allocated object. + // allocation. unsafe { ub_checks::assert_unsafe_precondition!( check_language_ub, @@ -1810,7 +1812,7 @@ pub const unsafe fn read_unaligned(src: *const T) -> T { let mut tmp = MaybeUninit::::uninit(); // SAFETY: the caller must guarantee that `src` is valid for reads. // `src` cannot overlap `tmp` because `tmp` was just allocated on - // the stack as a separate allocated object. + // the stack as a separate allocation. // // Also, since we just wrote a valid value into `tmp`, it is guaranteed // to be properly initialized. diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 040d91e912429..968f033bf5983 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -448,7 +448,7 @@ impl *mut T { // SAFETY: the caller must uphold the safety contract for `offset`. // The obtained pointer is valid for writes since the caller must - // guarantee that it points to the same allocated object as `self`. + // guarantee that it points to the same allocation as `self`. unsafe { intrinsics::offset(self, count) } } @@ -481,17 +481,17 @@ impl *mut T { /// /// This operation itself is always safe, but using the resulting pointer is not. /// - /// The resulting pointer "remembers" the [allocated object] that `self` points to + /// The resulting pointer "remembers" the [allocation] that `self` points to /// (this is called "[Provenance](ptr/index.html#provenance)"). - /// The pointer must not be used to read or write other allocated objects. + /// The pointer must not be used to read or write other allocations. /// /// In other words, `let z = x.wrapping_offset((y as isize) - (x as isize))` does *not* make `z` /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still /// attached to the object `x` is attached to, and dereferencing it is Undefined Behavior unless - /// `x` and `y` point into the same allocated object. + /// `x` and `y` point into the same allocation. /// /// Compared to [`offset`], this method basically delays the requirement of staying within the - /// same allocated object: [`offset`] is immediate Undefined Behavior when crossing object + /// same allocation: [`offset`] is immediate Undefined Behavior when crossing object /// boundaries; `wrapping_offset` produces a pointer but still leads to Undefined Behavior if a /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`offset`] /// can be optimized better and is thus preferable in performance-sensitive code. @@ -499,10 +499,10 @@ impl *mut T { /// The delayed check only considers the value of the pointer that was dereferenced, not the /// intermediate values used during the computation of the final result. For example, /// `x.wrapping_offset(o).wrapping_offset(o.wrapping_neg())` is always the same as `x`. In other - /// words, leaving the allocated object and then re-entering it later is permitted. + /// words, leaving the allocation and then re-entering it later is permitted. /// /// [`offset`]: #method.offset - /// [allocated object]: crate::ptr#allocated-object + /// [allocation]: crate::ptr#allocation /// /// # Examples /// @@ -791,7 +791,7 @@ impl *mut T { /// * `self` and `origin` must either /// /// * point to the same address, or - /// * both be [derived from][crate::ptr#provenance] a pointer to the same [allocated object], and the memory range between + /// * both be [derived from][crate::ptr#provenance] a pointer to the same [allocation], and the memory range between /// the two pointers must be in bounds of that object. (See below for an example.) /// /// * The distance between the pointers, in bytes, must be an exact multiple @@ -799,10 +799,10 @@ impl *mut T { /// /// As a consequence, the absolute distance between the pointers, in bytes, computed on /// mathematical integers (without "wrapping around"), cannot overflow an `isize`. This is - /// implied by the in-bounds requirement, and the fact that no allocated object can be larger + /// implied by the in-bounds requirement, and the fact that no allocation can be larger /// than `isize::MAX` bytes. /// - /// The requirement for pointers to be derived from the same allocated object is primarily + /// The requirement for pointers to be derived from the same allocation is primarily /// needed for `const`-compatibility: the distance between pointers into *different* allocated /// objects is not known at compile-time. However, the requirement also exists at /// runtime and may be exploited by optimizations. If you wish to compute the difference between @@ -811,7 +811,7 @@ impl *mut T { // FIXME: recommend `addr()` instead of `as usize` once that is stable. /// /// [`add`]: #method.add - /// [allocated object]: crate::ptr#allocated-object + /// [allocation]: crate::ptr#allocation /// /// # Panics /// @@ -1061,12 +1061,12 @@ impl *mut T { /// "wrapping around"), must fit in an `isize`. /// /// * If the computed offset is non-zero, then `self` must be [derived from][crate::ptr#provenance] a pointer to some - /// [allocated object], and the entire memory range between `self` and the result must be in - /// bounds of that allocated object. In particular, this range must not "wrap around" the edge + /// [allocation], and the entire memory range between `self` and the result must be in + /// bounds of that allocation. In particular, this range must not "wrap around" the edge /// of the address space. /// - /// Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset - /// stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement. + /// Allocations can never be larger than `isize::MAX` bytes, so if the computed offset + /// stays in bounds of the allocation, it is guaranteed to satisfy the first requirement. /// This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec`) is always /// safe. /// @@ -1075,7 +1075,7 @@ impl *mut T { /// enables more aggressive compiler optimizations. /// /// [`wrapping_sub`]: #method.wrapping_sub - /// [allocated object]: crate::ptr#allocated-object + /// [allocation]: crate::ptr#allocation /// /// # Examples /// @@ -1165,16 +1165,16 @@ impl *mut T { /// /// This operation itself is always safe, but using the resulting pointer is not. /// - /// The resulting pointer "remembers" the [allocated object] that `self` points to; it must not - /// be used to read or write other allocated objects. + /// The resulting pointer "remembers" the [allocation] that `self` points to; it must not + /// be used to read or write other allocations. /// /// In other words, `let z = x.wrapping_add((y as usize) - (x as usize))` does *not* make `z` /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still /// attached to the object `x` is attached to, and dereferencing it is Undefined Behavior unless - /// `x` and `y` point into the same allocated object. + /// `x` and `y` point into the same allocation. /// /// Compared to [`add`], this method basically delays the requirement of staying within the - /// same allocated object: [`add`] is immediate Undefined Behavior when crossing object + /// same allocation: [`add`] is immediate Undefined Behavior when crossing object /// boundaries; `wrapping_add` produces a pointer but still leads to Undefined Behavior if a /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`add`] /// can be optimized better and is thus preferable in performance-sensitive code. @@ -1182,10 +1182,10 @@ impl *mut T { /// The delayed check only considers the value of the pointer that was dereferenced, not the /// intermediate values used during the computation of the final result. For example, /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the - /// allocated object and then re-entering it later is permitted. + /// allocation and then re-entering it later is permitted. /// /// [`add`]: #method.add - /// [allocated object]: crate::ptr#allocated-object + /// [allocation]: crate::ptr#allocation /// /// # Examples /// @@ -1241,16 +1241,16 @@ impl *mut T { /// /// This operation itself is always safe, but using the resulting pointer is not. /// - /// The resulting pointer "remembers" the [allocated object] that `self` points to; it must not - /// be used to read or write other allocated objects. + /// The resulting pointer "remembers" the [allocation] that `self` points to; it must not + /// be used to read or write other allocations. /// /// In other words, `let z = x.wrapping_sub((x as usize) - (y as usize))` does *not* make `z` /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still /// attached to the object `x` is attached to, and dereferencing it is Undefined Behavior unless - /// `x` and `y` point into the same allocated object. + /// `x` and `y` point into the same allocation. /// /// Compared to [`sub`], this method basically delays the requirement of staying within the - /// same allocated object: [`sub`] is immediate Undefined Behavior when crossing object + /// same allocation: [`sub`] is immediate Undefined Behavior when crossing object /// boundaries; `wrapping_sub` produces a pointer but still leads to Undefined Behavior if a /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`sub`] /// can be optimized better and is thus preferable in performance-sensitive code. @@ -1258,10 +1258,10 @@ impl *mut T { /// The delayed check only considers the value of the pointer that was dereferenced, not the /// intermediate values used during the computation of the final result. For example, /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the - /// allocated object and then re-entering it later is permitted. + /// allocation and then re-entering it later is permitted. /// /// [`sub`]: #method.sub - /// [allocated object]: crate::ptr#allocated-object + /// [allocation]: crate::ptr#allocation /// /// # Examples /// @@ -1770,7 +1770,7 @@ impl *mut [T] { /// /// # Safety /// - /// `mid` must be [in-bounds] of the underlying [allocated object]. + /// `mid` must be [in-bounds] of the underlying [allocation]. /// Which means `self` must be dereferenceable and span a single allocation /// that is at least `mid * size_of::()` bytes long. Not upholding these /// requirements is *[undefined behavior]* even if the resulting pointers are not used. @@ -1781,7 +1781,7 @@ impl *mut [T] { /// /// [`split_at_mut_unchecked`]: #method.split_at_mut_unchecked /// [in-bounds]: #method.add - /// [allocated object]: crate::ptr#allocated-object + /// [allocation]: crate::ptr#allocation /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html /// /// # Examples @@ -1816,13 +1816,14 @@ impl *mut [T] { /// /// # Safety /// - /// `mid` must be [in-bounds] of the underlying [allocated object]. + /// `mid` must be [in-bounds] of the underlying [allocation]. /// Which means `self` must be dereferenceable and span a single allocation /// that is at least `mid * size_of::()` bytes long. Not upholding these /// requirements is *[undefined behavior]* even if the resulting pointers are not used. /// /// [in-bounds]: #method.add /// [out-of-bounds index]: #method.add + /// [allocation]: crate::ptr#allocation /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html /// /// # Examples @@ -1922,8 +1923,8 @@ impl *mut [T] { /// * The pointer must be [valid] for reads for `ptr.len() * size_of::()` many bytes, /// and it must be properly aligned. This means in particular: /// - /// * The entire memory range of this slice must be contained within a single [allocated object]! - /// Slices can never span across multiple allocated objects. + /// * The entire memory range of this slice must be contained within a single [allocation]! + /// Slices can never span across multiple allocations. /// /// * The pointer must be aligned even for zero-length slices. One /// reason for this is that enum layout optimizations may rely on references @@ -1944,7 +1945,7 @@ impl *mut [T] { /// See also [`slice::from_raw_parts`][]. /// /// [valid]: crate::ptr#safety - /// [allocated object]: crate::ptr#allocated-object + /// [allocation]: crate::ptr#allocation /// /// # Panics during const evaluation /// @@ -1980,8 +1981,8 @@ impl *mut [T] { /// * The pointer must be [valid] for reads and writes for `ptr.len() * size_of::()` /// many bytes, and it must be properly aligned. This means in particular: /// - /// * The entire memory range of this slice must be contained within a single [allocated object]! - /// Slices can never span across multiple allocated objects. + /// * The entire memory range of this slice must be contained within a single [allocation]! + /// Slices can never span across multiple allocations. /// /// * The pointer must be aligned even for zero-length slices. One /// reason for this is that enum layout optimizations may rely on references @@ -2002,7 +2003,7 @@ impl *mut [T] { /// See also [`slice::from_raw_parts_mut`][]. /// /// [valid]: crate::ptr#safety - /// [allocated object]: crate::ptr#allocated-object + /// [allocation]: crate::ptr#allocation /// /// # Panics during const evaluation /// diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 226b5229f1798..91b8d1bf9a707 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -530,16 +530,16 @@ impl NonNull { /// * The computed offset, `count * size_of::()` bytes, must not overflow `isize`. /// /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some - /// [allocated object], and the entire memory range between `self` and the result must be in - /// bounds of that allocated object. In particular, this range must not "wrap around" the edge + /// [allocation], and the entire memory range between `self` and the result must be in + /// bounds of that allocation. In particular, this range must not "wrap around" the edge /// of the address space. /// - /// Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset - /// stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement. + /// Allocations can never be larger than `isize::MAX` bytes, so if the computed offset + /// stays in bounds of the allocation, it is guaranteed to satisfy the first requirement. /// This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec`) is always /// safe. /// - /// [allocated object]: crate::ptr#allocated-object + /// [allocation]: crate::ptr#allocation /// /// # Examples /// @@ -606,16 +606,16 @@ impl NonNull { /// * The computed offset, `count * size_of::()` bytes, must not overflow `isize`. /// /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some - /// [allocated object], and the entire memory range between `self` and the result must be in - /// bounds of that allocated object. In particular, this range must not "wrap around" the edge + /// [allocation], and the entire memory range between `self` and the result must be in + /// bounds of that allocation. In particular, this range must not "wrap around" the edge /// of the address space. /// - /// Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset - /// stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement. + /// Allocations can never be larger than `isize::MAX` bytes, so if the computed offset + /// stays in bounds of the allocation, it is guaranteed to satisfy the first requirement. /// This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec`) is always /// safe. /// - /// [allocated object]: crate::ptr#allocated-object + /// [allocation]: crate::ptr#allocation /// /// # Examples /// @@ -683,16 +683,16 @@ impl NonNull { /// * The computed offset, `count * size_of::()` bytes, must not overflow `isize`. /// /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some - /// [allocated object], and the entire memory range between `self` and the result must be in - /// bounds of that allocated object. In particular, this range must not "wrap around" the edge + /// [allocation], and the entire memory range between `self` and the result must be in + /// bounds of that allocation. In particular, this range must not "wrap around" the edge /// of the address space. /// - /// Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset - /// stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement. + /// Allocations can never be larger than `isize::MAX` bytes, so if the computed offset + /// stays in bounds of the allocation, it is guaranteed to satisfy the first requirement. /// This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec`) is always /// safe. /// - /// [allocated object]: crate::ptr#allocated-object + /// [allocation]: crate::ptr#allocation /// /// # Examples /// @@ -775,7 +775,7 @@ impl NonNull { /// * `self` and `origin` must either /// /// * point to the same address, or - /// * both be *derived from* a pointer to the same [allocated object], and the memory range between + /// * both be *derived from* a pointer to the same [allocation], and the memory range between /// the two pointers must be in bounds of that object. (See below for an example.) /// /// * The distance between the pointers, in bytes, must be an exact multiple @@ -783,10 +783,10 @@ impl NonNull { /// /// As a consequence, the absolute distance between the pointers, in bytes, computed on /// mathematical integers (without "wrapping around"), cannot overflow an `isize`. This is - /// implied by the in-bounds requirement, and the fact that no allocated object can be larger + /// implied by the in-bounds requirement, and the fact that no allocation can be larger /// than `isize::MAX` bytes. /// - /// The requirement for pointers to be derived from the same allocated object is primarily + /// The requirement for pointers to be derived from the same allocation is primarily /// needed for `const`-compatibility: the distance between pointers into *different* allocated /// objects is not known at compile-time. However, the requirement also exists at /// runtime and may be exploited by optimizations. If you wish to compute the difference between @@ -795,7 +795,7 @@ impl NonNull { // FIXME: recommend `addr()` instead of `as usize` once that is stable. /// /// [`add`]: #method.add - /// [allocated object]: crate::ptr#allocated-object + /// [allocation]: crate::ptr#allocation /// /// # Panics /// @@ -1475,8 +1475,8 @@ impl NonNull<[T]> { /// * The pointer must be [valid] for reads for `ptr.len() * size_of::()` many bytes, /// and it must be properly aligned. This means in particular: /// - /// * The entire memory range of this slice must be contained within a single allocated object! - /// Slices can never span across multiple allocated objects. + /// * The entire memory range of this slice must be contained within a single allocation! + /// Slices can never span across multiple allocations. /// /// * The pointer must be aligned even for zero-length slices. One /// reason for this is that enum layout optimizations may rely on references @@ -1520,8 +1520,8 @@ impl NonNull<[T]> { /// * The pointer must be [valid] for reads and writes for `ptr.len() * size_of::()` /// many bytes, and it must be properly aligned. This means in particular: /// - /// * The entire memory range of this slice must be contained within a single allocated object! - /// Slices can never span across multiple allocated objects. + /// * The entire memory range of this slice must be contained within a single allocation! + /// Slices can never span across multiple allocations. /// /// * The pointer must be aligned even for zero-length slices. One /// reason for this is that enum layout optimizations may rely on references diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index 40da69c15627d..eba2f89a169a1 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -14,8 +14,8 @@ use crate::{array, ptr, ub_checks}; /// * `data` must be non-null, [valid] for reads for `len * size_of::()` many bytes, /// and it must be properly aligned. This means in particular: /// -/// * The entire memory range of this slice must be contained within a single allocated object! -/// Slices can never span across multiple allocated objects. See [below](#incorrect-usage) +/// * The entire memory range of this slice must be contained within a single allocation! +/// Slices can never span across multiple allocations. See [below](#incorrect-usage) /// for an example incorrectly not taking this into account. /// * `data` must be non-null and aligned even for zero-length slices or slices of ZSTs. One /// reason for this is that enum layout optimizations may rely on references @@ -65,14 +65,14 @@ use crate::{array, ptr, ub_checks}; /// assert_eq!(fst_end, snd_start, "Slices must be contiguous!"); /// unsafe { /// // The assertion above ensures `fst` and `snd` are contiguous, but they might -/// // still be contained within _different allocated objects_, in which case +/// // still be contained within _different allocations_, in which case /// // creating this slice is undefined behavior. /// slice::from_raw_parts(fst.as_ptr(), fst.len() + snd.len()) /// } /// } /// /// fn main() { -/// // `a` and `b` are different allocated objects... +/// // `a` and `b` are different allocations... /// let a = 42; /// let b = 27; /// // ... which may nevertheless be laid out contiguously in memory: | a | b | @@ -150,8 +150,8 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] /// * `data` must be non-null, [valid] for both reads and writes for `len * size_of::()` many bytes, /// and it must be properly aligned. This means in particular: /// -/// * The entire memory range of this slice must be contained within a single allocated object! -/// Slices can never span across multiple allocated objects. +/// * The entire memory range of this slice must be contained within a single allocation! +/// Slices can never span across multiple allocations. /// * `data` must be non-null and aligned even for zero-length slices or slices of ZSTs. One /// reason for this is that enum layout optimizations may rely on references /// (including slices of any length) being aligned and non-null to distinguish @@ -228,8 +228,8 @@ pub const fn from_mut(s: &mut T) -> &mut [T] { /// the last element, such that the offset from the end to the start pointer is /// the length of the slice. /// -/// * The entire memory range of this slice must be contained within a single allocated object! -/// Slices can never span across multiple allocated objects. +/// * The entire memory range of this slice must be contained within a single allocation! +/// Slices can never span across multiple allocations. /// /// * The range must contain `N` consecutive properly initialized values of type `T`. /// @@ -298,8 +298,8 @@ pub const unsafe fn from_ptr_range<'a, T>(range: Range<*const T>) -> &'a [T] { /// the last element, such that the offset from the end to the start pointer is /// the length of the slice. /// -/// * The entire memory range of this slice must be contained within a single allocated object! -/// Slices can never span across multiple allocated objects. +/// * The entire memory range of this slice must be contained within a single allocation! +/// Slices can never span across multiple allocations. /// /// * The range must contain `N` consecutive properly initialized values of type `T`. /// diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index eeba7780c65b3..6ef1b13abcde0 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs @@ -5,7 +5,6 @@ use std::path::PathBuf; -use crate::Mode; use crate::core::build_steps::dist::distdir; use crate::core::build_steps::test; use crate::core::build_steps::tool::{self, SourceType, Tool}; @@ -14,6 +13,7 @@ use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step}; use crate::core::config::TargetSelection; use crate::core::config::flags::get_completion; use crate::utils::exec::command; +use crate::{Mode, t}; #[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)] pub struct BuildManifest; @@ -253,6 +253,7 @@ impl Step for GenerateCopyright { cmd.env("SRC_DIR", &builder.src); cmd.env("VENDOR_DIR", &vendored_sources); cmd.env("CARGO", &builder.initial_cargo); + cmd.env("CARGO_HOME", t!(home::cargo_home())); // it is important that generate-copyright runs from the root of the // source tree, because it uses relative paths cmd.current_dir(&builder.src); diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 678aa9b01e4ad..76025d4020eac 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -1197,9 +1197,9 @@ fn run_tool_build_step( artifact_kind: ToolArtifactKind::Binary, }); - // FIXME: This should just be an if-let-chain, but those are unstable. - if let Some(add_bins_to_sysroot) = - add_bins_to_sysroot.filter(|bins| !bins.is_empty() && target_compiler.stage > 0) + if let Some(add_bins_to_sysroot) = add_bins_to_sysroot + && !add_bins_to_sysroot.is_empty() + && target_compiler.stage > 0 { let bindir = builder.sysroot(target_compiler).join("bin"); t!(fs::create_dir_all(&bindir)); diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index e41f6f16b0232..51556525bc999 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -1004,7 +1004,12 @@ impl Builder<'_> { // efficient initial-exec TLS model. This doesn't work with `dlopen`, // so we can't use it by default in general, but we can use it for tools // and our own internal libraries. - if !mode.must_support_dlopen() && !target.triple.starts_with("powerpc-") { + // + // Cygwin only supports emutls. + if !mode.must_support_dlopen() + && !target.triple.starts_with("powerpc-") + && !target.triple.contains("cygwin") + { cargo.env("RUSTC_TLS_MODEL_INITIAL_EXEC", "1"); } diff --git a/src/tools/generate-copyright/src/cargo_metadata.rs b/src/tools/generate-copyright/src/cargo_metadata.rs index b717bd53eb1a7..3fae26bda4752 100644 --- a/src/tools/generate-copyright/src/cargo_metadata.rs +++ b/src/tools/generate-copyright/src/cargo_metadata.rs @@ -46,11 +46,12 @@ pub struct PackageMetadata { /// covered it already. pub fn get_metadata_and_notices( cargo: &Path, + cargo_home_path: &Path, vendor_path: &Path, root_path: &Path, manifest_paths: &[PathBuf], ) -> Result, Error> { - let mut output = get_metadata(cargo, root_path, manifest_paths)?; + let mut output = get_metadata(cargo, cargo_home_path, root_path, manifest_paths)?; // Now for each dependency we found, go and grab any important looking files for (package, metadata) in output.iter_mut() { @@ -66,6 +67,7 @@ pub fn get_metadata_and_notices( /// assume `reuse` has covered it already. pub fn get_metadata( cargo: &Path, + cargo_home_path: &Path, root_path: &Path, manifest_paths: &[PathBuf], ) -> Result, Error> { @@ -81,8 +83,11 @@ pub fn get_metadata( .manifest_path(manifest_path) .exec()?; for package in metadata.packages { - let manifest_path = package.manifest_path.as_path(); - if manifest_path.starts_with(root_path) { + let package_manifest_path = package.manifest_path.as_path(); + + if package_manifest_path.starts_with(root_path) + && !package_manifest_path.starts_with(cargo_home_path) + { // it's an in-tree dependency and reuse covers it continue; } diff --git a/src/tools/generate-copyright/src/main.rs b/src/tools/generate-copyright/src/main.rs index d6ed7261b7c87..5497db1f5f3a9 100644 --- a/src/tools/generate-copyright/src/main.rs +++ b/src/tools/generate-copyright/src/main.rs @@ -15,6 +15,7 @@ mod cargo_metadata; /// /// Run `x.py run generate-copyright` fn main() -> Result<(), Error> { + let cargo_home = env_path("CARGO_HOME")?; let dest_file = env_path("DEST")?; let libstd_dest_file = env_path("DEST_LIBSTD")?; let src_dir = env_path("SRC_DIR")?; @@ -39,11 +40,17 @@ fn main() -> Result<(), Error> { .collect::>(); // Scan Cargo dependencies - let mut collected_cargo_metadata = - cargo_metadata::get_metadata_and_notices(&cargo, &vendor_dir, &src_dir, &cargo_manifests)?; + let mut collected_cargo_metadata = cargo_metadata::get_metadata_and_notices( + &cargo, + &cargo_home, + &vendor_dir, + &src_dir, + &cargo_manifests, + )?; let library_collected_cargo_metadata = cargo_metadata::get_metadata_and_notices( &cargo, + &cargo_home, &vendor_dir, &src_dir, &library_manifests, diff --git a/tests/crashes/140484.rs b/tests/crashes/140484.rs deleted file mode 100644 index 92ec19843982d..0000000000000 --- a/tests/crashes/140484.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ known-bug: #140484 -//@edition:2024 -#![feature(async_drop)] -use std::future::AsyncDrop; -struct a; -impl Drop for a { - fn b() {} -} -impl AsyncDrop for a { - type c; -} -async fn bar() { - a; -} diff --git a/tests/crashes/140500.rs b/tests/crashes/140500.rs deleted file mode 100644 index ee5b93ab82132..0000000000000 --- a/tests/crashes/140500.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ known-bug: #140500 - -#![feature(async_drop)] -use std::future::AsyncDrop; -struct a; -impl Drop for a { - fn b() {} -} -impl AsyncDrop for a { - fn c(d: impl Sized) {} -} -async fn bar() { - a; -} diff --git a/tests/ui/associated-type-bounds/return-type-notation/path-missing.stderr b/tests/ui/associated-type-bounds/return-type-notation/path-missing.stderr index edac09db89dae..677fc0e10bbda 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/path-missing.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/path-missing.stderr @@ -8,9 +8,7 @@ error[E0575]: expected method or associated constant, found associated type `A:: --> $DIR/path-missing.rs:12:5 | LL | ::bad(..): Send, - | ^^^^^^^^^^^^^^^^^ - | - = note: can't use a type alias as a constructor + | ^^^^^^^^^^^^^^^^^ not a method or associated constant error[E0220]: associated function `method` not found for `T` --> $DIR/path-missing.rs:19:8 diff --git a/tests/ui/associated-types/associated-type-tuple-struct-construction.rs b/tests/ui/associated-types/associated-type-tuple-struct-construction.rs deleted file mode 100644 index d5809ecd55d85..0000000000000 --- a/tests/ui/associated-types/associated-type-tuple-struct-construction.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Users cannot yet construct structs through associated types -// in both expressions and patterns - -#![feature(more_qualified_paths)] - -fn main() { - let ::Assoc(n) = ::Assoc(2); - //~^ ERROR expected method or associated constant, found associated type - //~| ERROR expected method or associated constant, found associated type - assert!(n == 2); -} - -struct TupleStruct(i8); - -struct Foo; - - -trait A { - type Assoc; -} - -impl A for Foo { - type Assoc = TupleStruct; -} diff --git a/tests/ui/associated-types/associated-type-tuple-struct-construction.stderr b/tests/ui/associated-types/associated-type-tuple-struct-construction.stderr deleted file mode 100644 index bca7deeb5128c..0000000000000 --- a/tests/ui/associated-types/associated-type-tuple-struct-construction.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0575]: expected method or associated constant, found associated type `A::Assoc` - --> $DIR/associated-type-tuple-struct-construction.rs:7:32 - | -LL | let ::Assoc(n) = ::Assoc(2); - | ^^^^^^^^^^^^^^^^^ - | - = note: can't use a type alias as a constructor - -error[E0575]: expected method or associated constant, found associated type `A::Assoc` - --> $DIR/associated-type-tuple-struct-construction.rs:7:9 - | -LL | let ::Assoc(n) = ::Assoc(2); - | ^^^^^^^^^^^^^^^^^ - | - = note: can't use a type alias as a constructor - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0575`. diff --git a/tests/ui/associated-types/tuple-struct-expr-pat.fixed b/tests/ui/associated-types/tuple-struct-expr-pat.fixed new file mode 100644 index 0000000000000..d6e2385f82103 --- /dev/null +++ b/tests/ui/associated-types/tuple-struct-expr-pat.fixed @@ -0,0 +1,48 @@ +// Check that fully qualified syntax can **not** be used in tuple struct expressions (calls) and +// patterns. Both tuple struct expressions and patterns are resolved in value namespace and thus +// can't be resolved through associated *types*. +// +//@ run-rustfix + +#![feature(more_qualified_paths)] + +fn main() { + let as Trait>::Assoc {} = as Trait>::Assoc {}; + //~^ error: expected method or associated constant, found associated type + //~| error: expected tuple struct or tuple variant, found associated type + let as Trait>::Assoc { 0: _a } = as Trait>::Assoc { 0: 0 }; + //~^ error: expected method or associated constant, found associated type + //~| error: expected tuple struct or tuple variant, found associated type + let as Trait>::Assoc { 0: _a, 1: _b } = as Trait>::Assoc { 0: 0, 1: 1 }; + //~^ error: expected method or associated constant, found associated type + //~| error: expected tuple struct or tuple variant, found associated type + let as Trait>::Assoc { 0: ref _a, 1: ref mut _b, 2: mut _c } = as Trait>::Assoc { 0: 0, 1: 1, 2: 2 }; + //~^ error: expected method or associated constant, found associated type + //~| error: expected tuple struct or tuple variant, found associated type +} + + +struct T; + +struct T0(); +struct T1(u8); +struct T2(u8, u8); +struct T3(u8, u8, u8); + +trait Trait { + type Assoc; +} + +impl Trait for T<0> { + type Assoc = T0; +} + +impl Trait for T<1> { + type Assoc = T1; +} +impl Trait for T<2> { + type Assoc = T2; +} +impl Trait for T<3> { + type Assoc = T3; +} diff --git a/tests/ui/associated-types/tuple-struct-expr-pat.rs b/tests/ui/associated-types/tuple-struct-expr-pat.rs new file mode 100644 index 0000000000000..f27a5fe175390 --- /dev/null +++ b/tests/ui/associated-types/tuple-struct-expr-pat.rs @@ -0,0 +1,48 @@ +// Check that fully qualified syntax can **not** be used in tuple struct expressions (calls) and +// patterns. Both tuple struct expressions and patterns are resolved in value namespace and thus +// can't be resolved through associated *types*. +// +//@ run-rustfix + +#![feature(more_qualified_paths)] + +fn main() { + let as Trait>::Assoc() = as Trait>::Assoc(); + //~^ error: expected method or associated constant, found associated type + //~| error: expected tuple struct or tuple variant, found associated type + let as Trait>::Assoc(_a) = as Trait>::Assoc(0); + //~^ error: expected method or associated constant, found associated type + //~| error: expected tuple struct or tuple variant, found associated type + let as Trait>::Assoc(_a, _b) = as Trait>::Assoc(0, 1); + //~^ error: expected method or associated constant, found associated type + //~| error: expected tuple struct or tuple variant, found associated type + let as Trait>::Assoc(ref _a, ref mut _b, mut _c) = as Trait>::Assoc(0, 1, 2); + //~^ error: expected method or associated constant, found associated type + //~| error: expected tuple struct or tuple variant, found associated type +} + + +struct T; + +struct T0(); +struct T1(u8); +struct T2(u8, u8); +struct T3(u8, u8, u8); + +trait Trait { + type Assoc; +} + +impl Trait for T<0> { + type Assoc = T0; +} + +impl Trait for T<1> { + type Assoc = T1; +} +impl Trait for T<2> { + type Assoc = T2; +} +impl Trait for T<3> { + type Assoc = T3; +} diff --git a/tests/ui/associated-types/tuple-struct-expr-pat.stderr b/tests/ui/associated-types/tuple-struct-expr-pat.stderr new file mode 100644 index 0000000000000..135dfcb3447e5 --- /dev/null +++ b/tests/ui/associated-types/tuple-struct-expr-pat.stderr @@ -0,0 +1,97 @@ +error[E0575]: expected method or associated constant, found associated type `Trait::Assoc` + --> $DIR/tuple-struct-expr-pat.rs:10:36 + | +LL | let as Trait>::Assoc() = as Trait>::Assoc(); + | ^^^^^^^^^^^^^^^^^^^^^^-- help: use struct expression instead: `{}` + | + = note: can't use a type alias as a constructor + +error[E0575]: expected tuple struct or tuple variant, found associated type `Trait::Assoc` + --> $DIR/tuple-struct-expr-pat.rs:10:9 + | +LL | let as Trait>::Assoc() = as Trait>::Assoc(); + | ^^^^^^^^^^^^^^^^^^^^^^-- help: use struct pattern instead: `{}` + | + = note: can't use a type alias as tuple pattern + +error[E0575]: expected method or associated constant, found associated type `Trait::Assoc` + --> $DIR/tuple-struct-expr-pat.rs:13:38 + | +LL | let as Trait>::Assoc(_a) = as Trait>::Assoc(0); + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: can't use a type alias as a constructor +help: use struct expression instead + | +LL - let as Trait>::Assoc(_a) = as Trait>::Assoc(0); +LL + let as Trait>::Assoc(_a) = as Trait>::Assoc { 0: 0 }; + | + +error[E0575]: expected tuple struct or tuple variant, found associated type `Trait::Assoc` + --> $DIR/tuple-struct-expr-pat.rs:13:9 + | +LL | let as Trait>::Assoc(_a) = as Trait>::Assoc(0); + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: can't use a type alias as tuple pattern +help: use struct pattern instead + | +LL - let as Trait>::Assoc(_a) = as Trait>::Assoc(0); +LL + let as Trait>::Assoc { 0: _a } = as Trait>::Assoc(0); + | + +error[E0575]: expected method or associated constant, found associated type `Trait::Assoc` + --> $DIR/tuple-struct-expr-pat.rs:16:42 + | +LL | let as Trait>::Assoc(_a, _b) = as Trait>::Assoc(0, 1); + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: can't use a type alias as a constructor +help: use struct expression instead + | +LL - let as Trait>::Assoc(_a, _b) = as Trait>::Assoc(0, 1); +LL + let as Trait>::Assoc(_a, _b) = as Trait>::Assoc { 0: 0, 1: 1 }; + | + +error[E0575]: expected tuple struct or tuple variant, found associated type `Trait::Assoc` + --> $DIR/tuple-struct-expr-pat.rs:16:9 + | +LL | let as Trait>::Assoc(_a, _b) = as Trait>::Assoc(0, 1); + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: can't use a type alias as tuple pattern +help: use struct pattern instead + | +LL - let as Trait>::Assoc(_a, _b) = as Trait>::Assoc(0, 1); +LL + let as Trait>::Assoc { 0: _a, 1: _b } = as Trait>::Assoc(0, 1); + | + +error[E0575]: expected method or associated constant, found associated type `Trait::Assoc` + --> $DIR/tuple-struct-expr-pat.rs:19:62 + | +LL | let as Trait>::Assoc(ref _a, ref mut _b, mut _c) = as Trait>::Assoc(0, 1, 2); + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: can't use a type alias as a constructor +help: use struct expression instead + | +LL - let as Trait>::Assoc(ref _a, ref mut _b, mut _c) = as Trait>::Assoc(0, 1, 2); +LL + let as Trait>::Assoc(ref _a, ref mut _b, mut _c) = as Trait>::Assoc { 0: 0, 1: 1, 2: 2 }; + | + +error[E0575]: expected tuple struct or tuple variant, found associated type `Trait::Assoc` + --> $DIR/tuple-struct-expr-pat.rs:19:9 + | +LL | let as Trait>::Assoc(ref _a, ref mut _b, mut _c) = as Trait>::Assoc(0, 1, 2); + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: can't use a type alias as tuple pattern +help: use struct pattern instead + | +LL - let as Trait>::Assoc(ref _a, ref mut _b, mut _c) = as Trait>::Assoc(0, 1, 2); +LL + let as Trait>::Assoc { 0: ref _a, 1: ref mut _b, 2: mut _c } = as Trait>::Assoc(0, 1, 2); + | + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0575`. diff --git a/tests/ui/async-await/async-drop/type-parameter.rs b/tests/ui/async-await/async-drop/type-parameter.rs new file mode 100644 index 0000000000000..dde5f9f8e6444 --- /dev/null +++ b/tests/ui/async-await/async-drop/type-parameter.rs @@ -0,0 +1,16 @@ +//@ edition: 2024 +// ex-ice: #140500 +#![crate_type = "lib"] +#![feature(async_drop)] +#![expect(incomplete_features)] +use std::future::AsyncDrop; +struct A; +impl Drop for A { + fn drop(&mut self) {} +} +impl AsyncDrop for A { + fn drop(_wrong: impl Sized) {} //~ ERROR: method `drop` has a `self: Pin<&mut Self>` declaration in the trait, but not in the impl +} +async fn bar() { + A; +} diff --git a/tests/ui/async-await/async-drop/type-parameter.stderr b/tests/ui/async-await/async-drop/type-parameter.stderr new file mode 100644 index 0000000000000..841576b839e68 --- /dev/null +++ b/tests/ui/async-await/async-drop/type-parameter.stderr @@ -0,0 +1,11 @@ +error[E0186]: method `drop` has a `self: Pin<&mut Self>` declaration in the trait, but not in the impl + --> $DIR/type-parameter.rs:12:5 + | +LL | fn drop(_wrong: impl Sized) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `self: Pin<&mut Self>` in impl + | + = note: `drop` from trait: `fn(Pin<&mut Self>) -> impl Future` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0186`. diff --git a/tests/ui/async-await/async-drop/unexpected-sort.rs b/tests/ui/async-await/async-drop/unexpected-sort.rs new file mode 100644 index 0000000000000..659e21eb24119 --- /dev/null +++ b/tests/ui/async-await/async-drop/unexpected-sort.rs @@ -0,0 +1,18 @@ +// Ex-ice: #140484 +//@ edition: 2024 +#![crate_type = "lib"] +#![allow(incomplete_features)] +#![allow(non_camel_case_types)] +#![feature(async_drop)] +use std::future::AsyncDrop; +struct a; +impl Drop for a { //~ ERROR: not all trait items implemented, missing: `drop` + fn b() {} //~ ERROR: method `b` is not a member of trait `Drop` +} +impl AsyncDrop for a { //~ ERROR: not all trait items implemented, missing: `drop` + type c = (); + //~^ ERROR: type `c` is not a member of trait `AsyncDrop` +} +async fn bar() { + a; +} diff --git a/tests/ui/async-await/async-drop/unexpected-sort.stderr b/tests/ui/async-await/async-drop/unexpected-sort.stderr new file mode 100644 index 0000000000000..a6e4f9fd57307 --- /dev/null +++ b/tests/ui/async-await/async-drop/unexpected-sort.stderr @@ -0,0 +1,32 @@ +error[E0407]: method `b` is not a member of trait `Drop` + --> $DIR/unexpected-sort.rs:10:5 + | +LL | fn b() {} + | ^^^^^^^^^ not a member of trait `Drop` + +error[E0437]: type `c` is not a member of trait `AsyncDrop` + --> $DIR/unexpected-sort.rs:13:5 + | +LL | type c = (); + | ^^^^^^^^^^^^ not a member of trait `AsyncDrop` + +error[E0046]: not all trait items implemented, missing: `drop` + --> $DIR/unexpected-sort.rs:9:1 + | +LL | impl Drop for a { + | ^^^^^^^^^^^^^^^ missing `drop` in implementation + | + = help: implement the missing item: `fn drop(&mut self) { todo!() }` + +error[E0046]: not all trait items implemented, missing: `drop` + --> $DIR/unexpected-sort.rs:12:1 + | +LL | impl AsyncDrop for a { + | ^^^^^^^^^^^^^^^^^^^^ missing `drop` in implementation + | + = help: implement the missing item: `async fn drop(self: Pin<&mut Self>) { todo!() }` + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0046, E0407, E0437. +For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/const-ptr/allowed_slices.rs b/tests/ui/const-ptr/allowed_slices.rs index e5b9966c60930..23f63ff5febf7 100644 --- a/tests/ui/const-ptr/allowed_slices.rs +++ b/tests/ui/const-ptr/allowed_slices.rs @@ -26,7 +26,7 @@ pub static S5: &[MaybeUninit] = unsafe { from_raw_parts((&D1) as *const _ as // is valid as [bool; 4], so this is not UB (it's basically a transmute) pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) }; -// Structs are considered single allocated objects, +// Structs are considered single allocations, // as long as you don't reinterpret padding as initialized // data everything is ok. pub static S7: &[u16] = unsafe { diff --git a/tests/ui/delegation/bad-resolve.stderr b/tests/ui/delegation/bad-resolve.stderr index 966387e1d6164..fc6811292a6ff 100644 --- a/tests/ui/delegation/bad-resolve.stderr +++ b/tests/ui/delegation/bad-resolve.stderr @@ -44,9 +44,7 @@ error[E0575]: expected method or associated constant, found associated type `Tra --> $DIR/bad-resolve.rs:27:11 | LL | reuse ::Type; - | ^^^^^^^^^^^^^^^^^^ - | - = note: can't use a type alias as a constructor + | ^^^^^^^^^^^^^^^^^^ not a method or associated constant error[E0576]: cannot find method or associated constant `baz` in trait `Trait` --> $DIR/bad-resolve.rs:30:25 diff --git a/tests/ui/delegation/glob-non-fn.stderr b/tests/ui/delegation/glob-non-fn.stderr index 4b918c53b8489..f63c8e88c6fae 100644 --- a/tests/ui/delegation/glob-non-fn.stderr +++ b/tests/ui/delegation/glob-non-fn.stderr @@ -38,9 +38,7 @@ error[E0423]: expected function, found associated type `Trait::Type` --> $DIR/glob-non-fn.rs:30:11 | LL | reuse Trait::* { &self.0 } - | ^^^^^ - | - = note: can't use a type alias as a constructor + | ^^^^^ not a function error[E0046]: not all trait items implemented, missing: `CONST`, `Type`, `method` --> $DIR/glob-non-fn.rs:29:1 diff --git a/tests/ui/namespace/namespace-mix.stderr b/tests/ui/namespace/namespace-mix.stderr index 412ea4aba30b8..200d31cc71011 100644 --- a/tests/ui/namespace/namespace-mix.stderr +++ b/tests/ui/namespace/namespace-mix.stderr @@ -7,7 +7,6 @@ LL | pub struct TS(); LL | check(m1::S); | ^^^^^ | - = note: can't use a type alias as a constructor help: a tuple struct with a similar name exists | LL | check(m1::TS); @@ -35,7 +34,6 @@ LL | check(xm1::S); LL | pub struct TS(); | ------------- similarly named tuple struct `TS` defined here | - = note: can't use a type alias as a constructor help: a tuple struct with a similar name exists | LL | check(xm1::TS); @@ -61,7 +59,6 @@ LL | TV(), LL | check(m7::V); | ^^^^^ | - = note: can't use a type alias as a constructor help: a tuple variant with a similar name exists | LL | check(m7::TV); @@ -89,7 +86,6 @@ LL | check(xm7::V); LL | TV(), | -- similarly named tuple variant `TV` defined here | - = note: can't use a type alias as a constructor help: a tuple variant with a similar name exists | LL | check(xm7::TV); diff --git a/tests/ui/resolve/tuple-struct-alias.stderr b/tests/ui/resolve/tuple-struct-alias.stderr index a739ea43eed47..bf026a499b8c2 100644 --- a/tests/ui/resolve/tuple-struct-alias.stderr +++ b/tests/ui/resolve/tuple-struct-alias.stderr @@ -6,8 +6,6 @@ LL | struct S(u8, u16); ... LL | A(..) => {} | ^ help: a tuple struct with a similar name exists: `S` - | - = note: can't use a type alias as a constructor error[E0423]: expected function, tuple struct or tuple variant, found type alias `A` --> $DIR/tuple-struct-alias.rs:5:13 @@ -16,9 +14,18 @@ LL | struct S(u8, u16); | ------------------ similarly named tuple struct `S` defined here ... LL | let s = A(0, 1); - | ^ help: a tuple struct with a similar name exists: `S` + | ^ + | +help: a tuple struct with a similar name exists + | +LL - let s = A(0, 1); +LL + let s = S(0, 1); + | +help: you might have meant to use `:` for type annotation + | +LL - let s = A(0, 1); +LL + let s: A(0, 1); | - = note: can't use a type alias as a constructor error: aborting due to 2 previous errors diff --git a/tests/ui/ufcs/ufcs-partially-resolved.stderr b/tests/ui/ufcs/ufcs-partially-resolved.stderr index 0a9c190cb3561..69d6bd74a736d 100644 --- a/tests/ui/ufcs/ufcs-partially-resolved.stderr +++ b/tests/ui/ufcs/ufcs-partially-resolved.stderr @@ -235,8 +235,6 @@ LL | ::X; | ^^^^^^^^^^^^- | | | help: an associated function with a similar name exists: `Z` - | - = note: can't use a type alias as a constructor error[E0575]: expected associated type, found associated function `Dr::Z` --> $DIR/ufcs-partially-resolved.rs:54:12