diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index b44553e4f6d3b..6101b90aea6da 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -339,24 +339,32 @@ pub fn llvm_global_features(sess: &Session) -> Vec { Some(_) | None => {} }; + let filter = |s: &str| { + if s.is_empty() { + return None; + } + let feature = if s.starts_with("+") || s.starts_with("-") { + &s[1..] + } else { + return Some(s.to_string()); + }; + // Rustc-specific feature requests like `+crt-static` or `-crt-static` + // are not passed down to LLVM. + if RUSTC_SPECIFIC_FEATURES.contains(&feature) { + return None; + } + // ... otherwise though we run through `to_llvm_feature` feature when + // passing requests down to LLVM. This means that all in-language + // features also work on the command line instead of having two + // different names when the LLVM name and the Rust name differ. + Some(format!("{}{}", &s[..1], to_llvm_feature(sess, feature))) + }; + // Features implied by an implicit or explicit `--target`. - features.extend( - sess.target - .features - .split(',') - .filter(|f| !f.is_empty() && !RUSTC_SPECIFIC_FEATURES.iter().any(|s| f.contains(s))) - .map(String::from), - ); + features.extend(sess.target.features.split(',').filter_map(&filter)); // -Ctarget-features - features.extend( - sess.opts - .cg - .target_feature - .split(',') - .filter(|f| !f.is_empty() && !RUSTC_SPECIFIC_FEATURES.iter().any(|s| f.contains(s))) - .map(String::from), - ); + features.extend(sess.opts.cg.target_feature.split(',').filter_map(&filter)); features } diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 401d379b0d161..929bdf2275582 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -340,6 +340,14 @@ impl<'a> Linker for GccLinker<'a> { } fn link_dylib(&mut self, lib: Symbol, verbatim: bool, as_needed: bool) { + if self.sess.target.os == "illumos" && lib.as_str() == "c" { + // libc will be added via late_link_args on illumos so that it will + // appear last in the library search order. + // FIXME: This should be replaced by a more complete and generic + // mechanism for controlling the order of library arguments passed + // to the linker. + return; + } if !as_needed { if self.sess.target.is_like_osx { // FIXME(81490): ld64 doesn't support these flags but macOS 11 @@ -813,11 +821,9 @@ impl<'a> Linker for MsvcLinker<'a> { } fn link_whole_staticlib(&mut self, lib: Symbol, verbatim: bool, _search_path: &[PathBuf]) { - self.link_staticlib(lib, verbatim); self.cmd.arg(format!("/WHOLEARCHIVE:{}{}", lib, if verbatim { "" } else { ".lib" })); } fn link_whole_rlib(&mut self, path: &Path) { - self.link_rlib(path); let mut arg = OsString::from("/WHOLEARCHIVE:"); arg.push(path); self.cmd.arg(arg); diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 03c83f9c07b5d..f9140609c0f3c 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -464,31 +464,9 @@ impl<'a> StripUnconfigured<'a> { return true; } }; - let error = |span, msg, suggestion: &str| { - let mut err = self.sess.parse_sess.span_diagnostic.struct_span_err(span, msg); - if !suggestion.is_empty() { - err.span_suggestion( - span, - "expected syntax is", - suggestion.into(), - Applicability::MaybeIncorrect, - ); - } - err.emit(); - true - }; - let span = meta_item.span; - match meta_item.meta_item_list() { - None => error(span, "`cfg` is not followed by parentheses", "cfg(/* predicate */)"), - Some([]) => error(span, "`cfg` predicate is not specified", ""), - Some([_, .., l]) => error(l.span(), "multiple `cfg` predicates are specified", ""), - Some([single]) => match single.meta_item() { - Some(meta_item) => { - attr::cfg_matches(meta_item, &self.sess.parse_sess, self.features) - } - None => error(single.span(), "`cfg` predicate key cannot be a literal", ""), - }, - } + parse_cfg(&meta_item, &self.sess).map_or(true, |meta_item| { + attr::cfg_matches(&meta_item, &self.sess.parse_sess, self.features) + }) }) } @@ -532,6 +510,32 @@ impl<'a> StripUnconfigured<'a> { } } +pub fn parse_cfg<'a>(meta_item: &'a MetaItem, sess: &Session) -> Option<&'a MetaItem> { + let error = |span, msg, suggestion: &str| { + let mut err = sess.parse_sess.span_diagnostic.struct_span_err(span, msg); + if !suggestion.is_empty() { + err.span_suggestion( + span, + "expected syntax is", + suggestion.into(), + Applicability::HasPlaceholders, + ); + } + err.emit(); + None + }; + let span = meta_item.span; + match meta_item.meta_item_list() { + None => error(span, "`cfg` is not followed by parentheses", "cfg(/* predicate */)"), + Some([]) => error(span, "`cfg` predicate is not specified", ""), + Some([_, .., l]) => error(l.span(), "multiple `cfg` predicates are specified", ""), + Some([single]) => match single.meta_item() { + Some(meta_item) => Some(meta_item), + None => error(single.span(), "`cfg` predicate key cannot be a literal", ""), + }, + } +} + fn is_cfg(sess: &Session, attr: &Attribute) -> bool { sess.check_name(attr, sym::cfg) } diff --git a/compiler/rustc_target/src/spec/illumos_base.rs b/compiler/rustc_target/src/spec/illumos_base.rs index 2e365d210f3f6..2b8e046c46b0e 100644 --- a/compiler/rustc_target/src/spec/illumos_base.rs +++ b/compiler/rustc_target/src/spec/illumos_base.rs @@ -6,6 +6,17 @@ pub fn opts() -> TargetOptions { late_link_args.insert( LinkerFlavor::Gcc, vec![ + // The illumos libc contains a stack unwinding implementation, as + // does libgcc_s. The latter implementation includes several + // additional symbols that are not always in base libc. To force + // the consistent use of just one unwinder, we ensure libc appears + // after libgcc_s in the NEEDED list for the resultant binary by + // ignoring any attempts to add it as a dynamic dependency until the + // very end. + // FIXME: This should be replaced by a more complete and generic + // mechanism for controlling the order of library arguments passed + // to the linker. + "-lc".to_string(), // LLVM will insert calls to the stack protector functions // "__stack_chk_fail" and "__stack_chk_guard" into code in native // object files. Some platforms include these symbols directly in diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_none_hermitkernel.rs b/compiler/rustc_target/src/spec/x86_64_unknown_none_hermitkernel.rs index 28d9801b78cb5..359cb0f6881de 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_none_hermitkernel.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_none_hermitkernel.rs @@ -11,7 +11,7 @@ pub fn target() -> Target { base.stack_probes = StackProbeType::Call; Target { - llvm_target: "x86_64-unknown-none-elf".to_string(), + llvm_target: "x86_64-unknown-hermit".to_string(), pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 0c6a33b91cea5..4d6caf07236e2 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -720,11 +720,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(in super::super) fn select_obligations_where_possible( &self, fallback_has_occurred: bool, - mutate_fullfillment_errors: impl Fn(&mut Vec>), + mutate_fulfillment_errors: impl Fn(&mut Vec>), ) { let result = self.fulfillment_cx.borrow_mut().select_where_possible(self); if let Err(mut errors) = result { - mutate_fullfillment_errors(&mut errors); + mutate_fulfillment_errors(&mut errors); self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred); } } diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 80b5a9d4e621a..3417bc0197253 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -986,7 +986,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { error.obligation.predicate.kind().skip_binder() { // If any of the type arguments in this path segment caused the - // `FullfillmentError`, point at its span (#61860). + // `FulfillmentError`, point at its span (#61860). for arg in path .segments .iter() diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 4914f196afbb5..7436edccf84bb 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -43,7 +43,7 @@ struct CheckWfFcxBuilder<'tcx> { impl<'tcx> CheckWfFcxBuilder<'tcx> { fn with_fcx(&mut self, f: F) where - F: for<'b> FnOnce(&FnCtxt<'b, 'tcx>, TyCtxt<'tcx>) -> Vec>, + F: for<'b> FnOnce(&FnCtxt<'b, 'tcx>) -> Vec>, { let id = self.id; let span = self.span; @@ -56,7 +56,7 @@ impl<'tcx> CheckWfFcxBuilder<'tcx> { // empty `param_env`. check_false_global_bounds(&fcx, span, id); } - let wf_tys = f(&fcx, fcx.tcx); + let wf_tys = f(&fcx); fcx.select_all_obligations_or_error(); fcx.regionck_item(id, span, &wf_tys); }); @@ -388,7 +388,7 @@ fn check_associated_item( debug!("check_associated_item: {:?}", item_id); let code = ObligationCauseCode::MiscObligation; - for_id(tcx, item_id, span).with_fcx(|fcx, tcx| { + for_id(tcx, item_id, span).with_fcx(|fcx| { let item = fcx.tcx.associated_item(fcx.tcx.hir().local_def_id(item_id)); let (mut implied_bounds, self_ty) = match item.container { @@ -409,7 +409,6 @@ fn check_associated_item( let sig = fcx.normalize_associated_types_in(span, sig); let hir_sig = sig_if_method.expect("bad signature for method"); check_fn_or_method( - tcx, fcx, item.ident.span, sig, @@ -467,9 +466,9 @@ fn check_type_defn<'tcx, F>( ) where F: for<'fcx> FnMut(&FnCtxt<'fcx, 'tcx>) -> Vec>, { - for_item(tcx, item).with_fcx(|fcx, fcx_tcx| { + for_item(tcx, item).with_fcx(|fcx| { let variants = lookup_fields(fcx); - let packed = fcx.tcx.adt_def(item.def_id).repr.packed(); + let packed = tcx.adt_def(item.def_id).repr.packed(); for variant in &variants { // For DST, or when drop needs to copy things around, all @@ -477,15 +476,14 @@ fn check_type_defn<'tcx, F>( let needs_drop_copy = || { packed && { let ty = variant.fields.last().unwrap().ty; - let ty = fcx.tcx.erase_regions(ty); + let ty = tcx.erase_regions(ty); if ty.needs_infer() { - fcx_tcx - .sess + tcx.sess .delay_span_bug(item.span, &format!("inference variables in {:?}", ty)); // Just treat unresolved type expression as if it needs drop. true } else { - ty.needs_drop(fcx_tcx, fcx_tcx.param_env(item.def_id)) + ty.needs_drop(tcx, tcx.param_env(item.def_id)) } } }; @@ -497,7 +495,7 @@ fn check_type_defn<'tcx, F>( let last = idx == variant.fields.len() - 1; fcx.register_bound( field.ty, - fcx.tcx.require_lang_item(LangItem::Sized, None), + tcx.require_lang_item(LangItem::Sized, None), traits::ObligationCause::new( field.span, fcx.body_id, @@ -524,11 +522,10 @@ fn check_type_defn<'tcx, F>( // Explicit `enum` discriminant values must const-evaluate successfully. if let Some(discr_def_id) = variant.explicit_discr { - let discr_substs = - InternalSubsts::identity_for_item(fcx.tcx, discr_def_id.to_def_id()); + let discr_substs = InternalSubsts::identity_for_item(tcx, discr_def_id.to_def_id()); let cause = traits::ObligationCause::new( - fcx.tcx.def_span(discr_def_id), + tcx.def_span(discr_def_id), fcx.body_id, traits::MiscObligation, ); @@ -539,12 +536,12 @@ fn check_type_defn<'tcx, F>( ty::WithOptConstParam::unknown(discr_def_id.to_def_id()), discr_substs, ) - .to_predicate(fcx.tcx), + .to_predicate(tcx), )); } } - check_where_clauses(tcx, fcx, item.span, item.def_id.to_def_id(), None); + check_where_clauses(fcx, item.span, item.def_id.to_def_id(), None); // No implied bounds in a struct definition. vec![] @@ -569,8 +566,9 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) { } } - for_item(tcx, item).with_fcx(|fcx, _| { - check_where_clauses(tcx, fcx, item.span, item.def_id.to_def_id(), None); + // FIXME: this shouldn't use an `FnCtxt` at all. + for_item(tcx, item).with_fcx(|fcx| { + check_where_clauses(fcx, item.span, item.def_id.to_def_id(), None); vec![] }); @@ -610,20 +608,12 @@ fn check_item_fn( span: Span, decl: &hir::FnDecl<'_>, ) { - for_id(tcx, item_id, span).with_fcx(|fcx, tcx| { - let def_id = fcx.tcx.hir().local_def_id(item_id); - let sig = fcx.tcx.fn_sig(def_id); + for_id(tcx, item_id, span).with_fcx(|fcx| { + let def_id = tcx.hir().local_def_id(item_id); + let sig = tcx.fn_sig(def_id); let sig = fcx.normalize_associated_types_in(span, sig); let mut implied_bounds = vec![]; - check_fn_or_method( - tcx, - fcx, - ident.span, - sig, - decl, - def_id.to_def_id(), - &mut implied_bounds, - ); + check_fn_or_method(fcx, ident.span, sig, decl, def_id.to_def_id(), &mut implied_bounds); implied_bounds }) } @@ -631,7 +621,7 @@ fn check_item_fn( fn check_item_type(tcx: TyCtxt<'_>, item_id: hir::HirId, ty_span: Span, allow_foreign_ty: bool) { debug!("check_item_type: {:?}", item_id); - for_id(tcx, item_id, ty_span).with_fcx(|fcx, tcx| { + for_id(tcx, item_id, ty_span).with_fcx(|fcx| { let ty = tcx.type_of(tcx.hir().local_def_id(item_id)); let item_ty = fcx.normalize_associated_types_in(ty_span, ty); @@ -647,7 +637,7 @@ fn check_item_type(tcx: TyCtxt<'_>, item_id: hir::HirId, ty_span: Span, allow_fo if forbid_unsized { fcx.register_bound( item_ty, - fcx.tcx.require_lang_item(LangItem::Sized, None), + tcx.require_lang_item(LangItem::Sized, None), traits::ObligationCause::new(ty_span, fcx.body_id, traits::MiscObligation), ); } @@ -665,13 +655,13 @@ fn check_impl<'tcx>( ) { debug!("check_impl: {:?}", item); - for_item(tcx, item).with_fcx(|fcx, tcx| { + for_item(tcx, item).with_fcx(|fcx| { match *ast_trait_ref { Some(ref ast_trait_ref) => { // `#[rustc_reservation_impl]` impls are not real impls and // therefore don't need to be WF (the trait's `Self: Trait` predicate // won't hold). - let trait_ref = fcx.tcx.impl_trait_ref(item.def_id).unwrap(); + let trait_ref = tcx.impl_trait_ref(item.def_id).unwrap(); let trait_ref = fcx.normalize_associated_types_in(ast_trait_ref.path.span, trait_ref); let obligations = traits::wf::trait_obligations( @@ -687,7 +677,7 @@ fn check_impl<'tcx>( } } None => { - let self_ty = fcx.tcx.type_of(item.def_id); + let self_ty = tcx.type_of(item.def_id); let self_ty = fcx.normalize_associated_types_in(item.span, self_ty); fcx.register_wf_obligation( self_ty.into(), @@ -697,7 +687,7 @@ fn check_impl<'tcx>( } } - check_where_clauses(tcx, fcx, item.span, item.def_id.to_def_id(), None); + check_where_clauses(fcx, item.span, item.def_id.to_def_id(), None); fcx.impl_implied_bounds(item.def_id.to_def_id(), item.span) }); @@ -705,15 +695,15 @@ fn check_impl<'tcx>( /// Checks where-clauses and inline bounds that are declared on `def_id`. fn check_where_clauses<'tcx, 'fcx>( - tcx: TyCtxt<'tcx>, fcx: &FnCtxt<'fcx, 'tcx>, span: Span, def_id: DefId, return_ty: Option<(Ty<'tcx>, Span)>, ) { debug!("check_where_clauses(def_id={:?}, return_ty={:?})", def_id, return_ty); + let tcx = fcx.tcx; - let predicates = fcx.tcx.predicates_of(def_id); + let predicates = tcx.predicates_of(def_id); let generics = tcx.generics_of(def_id); let is_our_default = |def: &ty::GenericParamDef| match def.kind { @@ -734,14 +724,14 @@ fn check_where_clauses<'tcx, 'fcx>( match param.kind { GenericParamDefKind::Type { .. } => { if is_our_default(¶m) { - let ty = fcx.tcx.type_of(param.def_id); + let ty = tcx.type_of(param.def_id); // Ignore dependent defaults -- that is, where the default of one type // parameter includes another (e.g., ``). In those cases, we can't // be sure if it will error or not as user might always specify the other. if !ty.needs_subst() { fcx.register_wf_obligation( ty.into(), - fcx.tcx.def_span(param.def_id), + tcx.def_span(param.def_id), ObligationCauseCode::MiscObligation, ); } @@ -754,7 +744,7 @@ fn check_where_clauses<'tcx, 'fcx>( let default_ct = tcx.const_param_default(param.def_id); fcx.register_wf_obligation( default_ct.into(), - fcx.tcx.def_span(param.def_id), + tcx.def_span(param.def_id), ObligationCauseCode::MiscObligation, ); } @@ -772,17 +762,17 @@ fn check_where_clauses<'tcx, 'fcx>( // For more examples see tests `defaults-well-formedness.rs` and `type-check-defaults.rs`. // // First we build the defaulted substitution. - let substs = InternalSubsts::for_item(fcx.tcx, def_id, |param, _| { + let substs = InternalSubsts::for_item(tcx, def_id, |param, _| { match param.kind { GenericParamDefKind::Lifetime => { // All regions are identity. - fcx.tcx.mk_param_from_def(param) + tcx.mk_param_from_def(param) } GenericParamDefKind::Type { .. } => { // If the param has a default, ... if is_our_default(param) { - let default_ty = fcx.tcx.type_of(param.def_id); + let default_ty = tcx.type_of(param.def_id); // ... and it's not a dependent default, ... if !default_ty.needs_subst() { // ... then substitute it with the default. @@ -790,7 +780,7 @@ fn check_where_clauses<'tcx, 'fcx>( } } - fcx.tcx.mk_param_from_def(param) + tcx.mk_param_from_def(param) } GenericParamDefKind::Const { .. } => { // FIXME(const_generics_defaults): I(@lcnr) feel like always @@ -811,7 +801,7 @@ fn check_where_clauses<'tcx, 'fcx>( } } - fcx.tcx.mk_param_from_def(param) + tcx.mk_param_from_def(param) } } }); @@ -848,7 +838,7 @@ fn check_where_clauses<'tcx, 'fcx>( } let mut param_count = CountParams::default(); let has_region = pred.visit_with(&mut param_count).is_break(); - let substituted_pred = pred.subst(fcx.tcx, substs); + let substituted_pred = pred.subst(tcx, substs); // Don't check non-defaulted params, dependent defaults (including lifetimes) // or preds with multiple params. if substituted_pred.has_param_types_or_consts() @@ -879,14 +869,14 @@ fn check_where_clauses<'tcx, 'fcx>( traits::Obligation::new(cause, fcx.param_env, pred) }); - let predicates = predicates.instantiate_identity(fcx.tcx); + let predicates = predicates.instantiate_identity(tcx); if let Some((mut return_ty, span)) = return_ty { if return_ty.has_infer_types_or_consts() { fcx.select_obligations_where_possible(false, |_| {}); return_ty = fcx.resolve_vars_if_possible(return_ty); } - check_opaque_types(tcx, fcx, def_id.expect_local(), span, return_ty); + check_opaque_types(fcx, def_id.expect_local(), span, return_ty); } let predicates = fcx.normalize_associated_types_in(span, predicates); @@ -905,7 +895,6 @@ fn check_where_clauses<'tcx, 'fcx>( } fn check_fn_or_method<'fcx, 'tcx>( - tcx: TyCtxt<'tcx>, fcx: &FnCtxt<'fcx, 'tcx>, span: Span, sig: ty::PolyFnSig<'tcx>, @@ -930,7 +919,7 @@ fn check_fn_or_method<'fcx, 'tcx>( // FIXME(#25759) return types should not be implied bounds implied_bounds.push(sig.output()); - check_where_clauses(tcx, fcx, span, def_id, Some((sig.output(), hir_decl.output.span()))); + check_where_clauses(fcx, span, def_id, Some((sig.output(), hir_decl.output.span()))); } /// Checks "defining uses" of opaque `impl Trait` types to ensure that they meet the restrictions @@ -953,15 +942,16 @@ fn check_fn_or_method<'fcx, 'tcx>( /// ``` /// fn check_opaque_types<'fcx, 'tcx>( - tcx: TyCtxt<'tcx>, fcx: &FnCtxt<'fcx, 'tcx>, fn_def_id: LocalDefId, span: Span, ty: Ty<'tcx>, ) { - trace!("check_opaque_types(ty={:?})", ty); + trace!("check_opaque_types(fn_def_id={:?}, ty={:?})", fn_def_id, ty); + let tcx = fcx.tcx; + ty.fold_with(&mut ty::fold::BottomUpFolder { - tcx: fcx.tcx, + tcx, ty_op: |ty| { if let ty::Opaque(def_id, substs) = *ty.kind() { trace!("check_opaque_types: opaque_ty, {:?}, {:?}", def_id, substs); diff --git a/library/std/src/sys/sgx/abi/tls.rs b/library/std/src/sys/sgx/abi/tls/mod.rs similarity index 100% rename from library/std/src/sys/sgx/abi/tls.rs rename to library/std/src/sys/sgx/abi/tls/mod.rs diff --git a/library/std/src/sys/sgx/mutex.rs b/library/std/src/sys/sgx/mutex.rs index 8874517dac60c..1b5ced4178f6a 100644 --- a/library/std/src/sys/sgx/mutex.rs +++ b/library/std/src/sys/sgx/mutex.rs @@ -8,7 +8,7 @@ pub struct Mutex { inner: SpinMutex>, } -pub type MovableMutex = Box; +pub type MovableMutex = Mutex; // Implementation according to “Operating Systems: Three Easy Pieces”, chapter 28 impl Mutex { diff --git a/library/std/src/sys/sgx/waitqueue.rs b/library/std/src/sys/sgx/waitqueue/mod.rs similarity index 97% rename from library/std/src/sys/sgx/waitqueue.rs rename to library/std/src/sys/sgx/waitqueue/mod.rs index e464dc3ee9d40..61bb11d9a6fad 100644 --- a/library/std/src/sys/sgx/waitqueue.rs +++ b/library/std/src/sys/sgx/waitqueue/mod.rs @@ -13,13 +13,8 @@ #[cfg(test)] mod tests; -/// A doubly-linked list where callers are in charge of memory allocation -/// of the nodes in the list. -mod unsafe_list; - -/// Trivial spinlock-based implementation of `sync::Mutex`. -// FIXME: Perhaps use Intel TSX to avoid locking? mod spin_mutex; +mod unsafe_list; use crate::num::NonZeroUsize; use crate::ops::{Deref, DerefMut}; diff --git a/library/std/src/sys/sgx/waitqueue/spin_mutex.rs b/library/std/src/sys/sgx/waitqueue/spin_mutex.rs index 7f1a671bab4eb..f6e851ccaddfa 100644 --- a/library/std/src/sys/sgx/waitqueue/spin_mutex.rs +++ b/library/std/src/sys/sgx/waitqueue/spin_mutex.rs @@ -1,3 +1,6 @@ +//! Trivial spinlock-based implementation of `sync::Mutex`. +// FIXME: Perhaps use Intel TSX to avoid locking? + #[cfg(test)] mod tests; diff --git a/library/std/src/sys/sgx/waitqueue/unsafe_list.rs b/library/std/src/sys/sgx/waitqueue/unsafe_list.rs index 0834d2593fc32..cf2f0886c1546 100644 --- a/library/std/src/sys/sgx/waitqueue/unsafe_list.rs +++ b/library/std/src/sys/sgx/waitqueue/unsafe_list.rs @@ -1,3 +1,6 @@ +//! A doubly-linked list where callers are in charge of memory allocation +//! of the nodes in the list. + #[cfg(test)] mod tests; diff --git a/library/std/src/sys/unsupported/args.rs b/library/std/src/sys/unsupported/args.rs index c924a7d8a2672..a2d75a6197633 100644 --- a/library/std/src/sys/unsupported/args.rs +++ b/library/std/src/sys/unsupported/args.rs @@ -1,4 +1,5 @@ use crate::ffi::OsString; +use crate::fmt; pub struct Args {} diff --git a/library/std/src/sys/wasm/args.rs b/library/std/src/sys/wasm/args.rs deleted file mode 100644 index fde1ab79e1f4b..0000000000000 --- a/library/std/src/sys/wasm/args.rs +++ /dev/null @@ -1,42 +0,0 @@ -use crate::ffi::OsString; -use crate::fmt; -use crate::vec; - -pub fn args() -> Args { - Args { iter: Vec::new().into_iter() } -} - -pub struct Args { - iter: vec::IntoIter, -} - -impl !Send for Args {} -impl !Sync for Args {} - -impl fmt::Debug for Args { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.iter.as_slice().fmt(f) - } -} - -impl Iterator for Args { - type Item = OsString; - fn next(&mut self) -> Option { - self.iter.next() - } - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } -} - -impl ExactSizeIterator for Args { - fn len(&self) -> usize { - self.iter.len() - } -} - -impl DoubleEndedIterator for Args { - fn next_back(&mut self) -> Option { - self.iter.next_back() - } -} diff --git a/library/std/src/sys/wasm/condvar_atomics.rs b/library/std/src/sys/wasm/atomics/condvar.rs similarity index 100% rename from library/std/src/sys/wasm/condvar_atomics.rs rename to library/std/src/sys/wasm/atomics/condvar.rs diff --git a/library/std/src/sys/wasm/futex_atomics.rs b/library/std/src/sys/wasm/atomics/futex.rs similarity index 100% rename from library/std/src/sys/wasm/futex_atomics.rs rename to library/std/src/sys/wasm/atomics/futex.rs diff --git a/library/std/src/sys/wasm/mutex_atomics.rs b/library/std/src/sys/wasm/atomics/mutex.rs similarity index 100% rename from library/std/src/sys/wasm/mutex_atomics.rs rename to library/std/src/sys/wasm/atomics/mutex.rs diff --git a/library/std/src/sys/wasm/rwlock_atomics.rs b/library/std/src/sys/wasm/atomics/rwlock.rs similarity index 100% rename from library/std/src/sys/wasm/rwlock_atomics.rs rename to library/std/src/sys/wasm/atomics/rwlock.rs diff --git a/library/std/src/sys/wasm/thread.rs b/library/std/src/sys/wasm/atomics/thread.rs similarity index 83% rename from library/std/src/sys/wasm/thread.rs rename to library/std/src/sys/wasm/atomics/thread.rs index b7bf95c89b482..54bc877aa7de7 100644 --- a/library/std/src/sys/wasm/thread.rs +++ b/library/std/src/sys/wasm/atomics/thread.rs @@ -13,20 +13,10 @@ impl Thread { unsupported() } - pub fn yield_now() { - // do nothing - } + pub fn yield_now() {} - pub fn set_name(_name: &CStr) { - // nope - } + pub fn set_name(_name: &CStr) {} - #[cfg(not(target_feature = "atomics"))] - pub fn sleep(_dur: Duration) { - panic!("can't sleep"); - } - - #[cfg(target_feature = "atomics")] pub fn sleep(dur: Duration) { use crate::arch::wasm32; use crate::cmp; @@ -46,9 +36,7 @@ impl Thread { } } - pub fn join(self) { - self.0 - } + pub fn join(self) {} } pub mod guard { @@ -61,11 +49,9 @@ pub mod guard { } } -// This is only used by atomics primitives when the `atomics` feature is -// enabled. In that mode we currently just use our own thread-local to store our +// We currently just use our own thread-local to store our // current thread's ID, and then we lazily initialize it to something allocated // from a global counter. -#[cfg(target_feature = "atomics")] pub fn my_id() -> u32 { use crate::sync::atomic::{AtomicU32, Ordering::SeqCst}; diff --git a/library/std/src/sys/wasm/mod.rs b/library/std/src/sys/wasm/mod.rs index afcc5ca9286d3..cd701a333f84c 100644 --- a/library/std/src/sys/wasm/mod.rs +++ b/library/std/src/sys/wasm/mod.rs @@ -17,6 +17,7 @@ #![deny(unsafe_op_in_unsafe_fn)] pub mod alloc; +#[path = "../unsupported/args.rs"] pub mod args; #[path = "../unix/cmath.rs"] pub mod cmath; @@ -37,7 +38,6 @@ pub mod pipe; pub mod process; #[path = "../unsupported/stdio.rs"] pub mod stdio; -pub mod thread; #[path = "../unsupported/thread_local_dtor.rs"] pub mod thread_local_dtor; #[path = "../unsupported/thread_local_key.rs"] @@ -49,14 +49,16 @@ pub use crate::sys_common::os_str_bytes as os_str; cfg_if::cfg_if! { if #[cfg(target_feature = "atomics")] { - #[path = "condvar_atomics.rs"] + #[path = "atomics/condvar.rs"] pub mod condvar; - #[path = "mutex_atomics.rs"] + #[path = "atomics/mutex.rs"] pub mod mutex; - #[path = "rwlock_atomics.rs"] + #[path = "atomics/rwlock.rs"] pub mod rwlock; - #[path = "futex_atomics.rs"] + #[path = "atomics/futex.rs"] pub mod futex; + #[path = "atomics/thread.rs"] + pub mod thread; } else { #[path = "../unsupported/condvar.rs"] pub mod condvar; @@ -64,6 +66,8 @@ cfg_if::cfg_if! { pub mod mutex; #[path = "../unsupported/rwlock.rs"] pub mod rwlock; + #[path = "../unsupported/thread.rs"] + pub mod thread; } } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 5974cd878dd0c..6d05ac073cca3 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -317,10 +317,10 @@ fn merge_attrs( } else { Attributes::from_ast(&both, None) }, - both.cfg(cx.sess().diagnostic()), + both.cfg(cx.sess()), ) } else { - (old_attrs.clean(cx), old_attrs.cfg(cx.sess().diagnostic())) + (old_attrs.clean(cx), old_attrs.cfg(cx.sess())) } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 411cfab9f06a0..e1dde8eeaf84a 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2018,7 +2018,7 @@ fn clean_extern_crate( def_id: crate_def_id.into(), visibility: krate.vis.clean(cx), kind: box ExternCrateItem { src: orig_name }, - cfg: attrs.cfg(cx.sess().diagnostic()), + cfg: attrs.cfg(cx.sess()), }] } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 47dae63f1fdf7..9861e838e33f1 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -444,7 +444,7 @@ impl Item { kind, box ast_attrs.clean(cx), cx, - ast_attrs.cfg(cx.sess().diagnostic()), + ast_attrs.cfg(cx.sess()), ) } @@ -456,7 +456,7 @@ impl Item { cx: &mut DocContext<'_>, cfg: Option>, ) -> Item { - debug!("name={:?}, def_id={:?}", name, def_id); + trace!("name={:?}, def_id={:?}", name, def_id); Item { def_id: def_id.into(), @@ -795,7 +795,7 @@ crate trait AttributesExt { fn other_attrs(&self) -> Vec; - fn cfg(&self, diagnostic: &::rustc_errors::Handler) -> Option>; + fn cfg(&self, sess: &Session) -> Option>; } impl AttributesExt for [ast::Attribute] { @@ -820,17 +820,28 @@ impl AttributesExt for [ast::Attribute] { self.iter().filter(|attr| attr.doc_str().is_none()).cloned().collect() } - fn cfg(&self, diagnostic: &::rustc_errors::Handler) -> Option> { + fn cfg(&self, sess: &Session) -> Option> { let mut cfg = Cfg::True; for attr in self.iter() { + // #[doc] if attr.doc_str().is_none() && attr.has_name(sym::doc) { - if let Some(mi) = attr.meta() { - if let Some(cfg_mi) = Attributes::extract_cfg(&mi) { - // Extracted #[doc(cfg(...))] - match Cfg::parse(cfg_mi) { - Ok(new_cfg) => cfg &= new_cfg, - Err(e) => diagnostic.span_err(e.span, e.msg), + // #[doc(...)] + if let Some(list) = attr.meta().as_ref().and_then(|mi| mi.meta_item_list()) { + for item in list { + // #[doc(include)] + if !item.has_name(sym::cfg) { + continue; + } + // #[doc(cfg(...))] + if let Some(cfg_mi) = item + .meta_item() + .and_then(|item| rustc_expand::config::parse_cfg(&item, sess)) + { + match Cfg::parse(&cfg_mi) { + Ok(new_cfg) => cfg &= new_cfg, + Err(e) => sess.span_err(e.span, e.msg), + } } } } @@ -997,29 +1008,6 @@ impl Attributes { self.other_attrs.lists(name) } - /// Extracts the content from an attribute `#[doc(cfg(content))]`. - crate fn extract_cfg(mi: &ast::MetaItem) -> Option<&ast::MetaItem> { - use rustc_ast::NestedMetaItem::MetaItem; - - if let ast::MetaItemKind::List(ref nmis) = mi.kind { - if nmis.len() == 1 { - if let MetaItem(ref cfg_mi) = nmis[0] { - if cfg_mi.has_name(sym::cfg) { - if let ast::MetaItemKind::List(ref cfg_nmis) = cfg_mi.kind { - if cfg_nmis.len() == 1 { - if let MetaItem(ref content_mi) = cfg_nmis[0] { - return Some(content_mi); - } - } - } - } - } - } - } - - None - } - /// Reads a `MetaItem` from within an attribute, looks for whether it is a /// `#[doc(include="file")]`, and returns the filename and contents of the file as loaded from /// its expansion. diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index c0157121e1923..e563889f776e5 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -1096,7 +1096,7 @@ impl<'a, 'hir, 'tcx> HirCollector<'a, 'hir, 'tcx> { let ast_attrs = self.tcx.hir().attrs(hir_id); let mut attrs = Attributes::from_ast(ast_attrs, None); - if let Some(ref cfg) = ast_attrs.cfg(self.sess.diagnostic()) { + if let Some(ref cfg) = ast_attrs.cfg(self.sess) { if !cfg.matches(&self.sess.parse_sess, Some(&self.sess.features_untracked())) { return; } diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 2f3f87215c3a1..e0c1fd06e7b6c 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -155,7 +155,7 @@ impl<'tcx> Context<'tcx> { &self.cache } - fn sess(&self) -> &'tcx Session { + pub(super) fn sess(&self) -> &'tcx Session { &self.shared.tcx.sess } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 70b5458ece894..9d4ac3cf015dd 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -296,7 +296,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl let import_item = clean::Item { def_id: import_def_id.into(), attrs: import_attrs, - cfg: ast_attrs.cfg(cx.tcx().sess.diagnostic()), + cfg: ast_attrs.cfg(cx.sess()), ..myitem.clone() }; diff --git a/src/test/rustdoc-ui/invalid-cfg.rs b/src/test/rustdoc-ui/invalid-cfg.rs new file mode 100644 index 0000000000000..d237b8605c068 --- /dev/null +++ b/src/test/rustdoc-ui/invalid-cfg.rs @@ -0,0 +1,4 @@ +#![feature(doc_cfg)] +#[doc(cfg = "x")] //~ ERROR not followed by parentheses +#[doc(cfg(x, y))] //~ ERROR multiple `cfg` predicates +struct S {} diff --git a/src/test/rustdoc-ui/invalid-cfg.stderr b/src/test/rustdoc-ui/invalid-cfg.stderr new file mode 100644 index 0000000000000..dae238b052b8a --- /dev/null +++ b/src/test/rustdoc-ui/invalid-cfg.stderr @@ -0,0 +1,14 @@ +error: `cfg` is not followed by parentheses + --> $DIR/invalid-cfg.rs:2:7 + | +LL | #[doc(cfg = "x")] + | ^^^^^^^^^ help: expected syntax is: `cfg(/* predicate */)` + +error: multiple `cfg` predicates are specified + --> $DIR/invalid-cfg.rs:3:14 + | +LL | #[doc(cfg(x, y))] + | ^ + +error: aborting due to 2 previous errors + diff --git a/src/test/rustdoc/doc-cfg.rs b/src/test/rustdoc/doc-cfg.rs index 89a61a289fdeb..1fc80b3e76c53 100644 --- a/src/test/rustdoc/doc-cfg.rs +++ b/src/test/rustdoc/doc-cfg.rs @@ -91,3 +91,11 @@ pub unsafe fn uses_target_feature() { pub fn uses_cfg_target_feature() { uses_target_feature(); } + +// multiple attributes should be allowed +// @has doc_cfg/fn.multiple_attrs.html \ +// '//*[@id="main"]/*[@class="item-info"]/*[@class="stab portability"]' \ +// 'This is supported on x and y and z only.' +#[doc(inline, cfg(x))] +#[doc(cfg(y), cfg(z))] +pub fn multiple_attrs() {} diff --git a/src/test/ui/target-feature/rust-specific-name-no-warnings.rs b/src/test/ui/target-feature/rust-specific-name-no-warnings.rs new file mode 100644 index 0000000000000..1708a71a9812f --- /dev/null +++ b/src/test/ui/target-feature/rust-specific-name-no-warnings.rs @@ -0,0 +1,5 @@ +// build-pass +// only-x86 +// compile-flags: -C target-feature=+pclmulqdq + +fn main() {}