diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 878a670cba3ef..663a6f3a27756 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -336,6 +336,7 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>( | NativeLibKind::Dylib { .. } | NativeLibKind::Framework { .. } | NativeLibKind::RawDylib + | NativeLibKind::LinkArg | NativeLibKind::Unspecified => continue, } if let Some(name) = lib.name { @@ -1287,6 +1288,7 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) { } // These are included, no need to print them NativeLibKind::Static { bundle: None | Some(true), .. } + | NativeLibKind::LinkArg | NativeLibKind::RawDylib => None, } }) @@ -2225,6 +2227,9 @@ fn add_local_native_libraries( // FIXME(#58713): Proper handling for raw dylibs. bug!("raw_dylib feature not yet implemented"); } + NativeLibKind::LinkArg => { + cmd.arg(name); + } } } } @@ -2362,19 +2367,34 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( (lib.name, lib.kind, lib.verbatim) }; - if let NativeLibKind::Static { bundle: Some(false), whole_archive } = - lib.kind - { - let verbatim = lib.verbatim.unwrap_or(false); - if whole_archive == Some(true) { + match lib.kind { + NativeLibKind::Static { + bundle: Some(false), + whole_archive: Some(true), + } => { cmd.link_whole_staticlib( name, - verbatim, + lib.verbatim.unwrap_or(false), search_path.get_or_init(|| archive_search_paths(sess)), ); - } else { - cmd.link_staticlib(name, verbatim); } + NativeLibKind::Static { + bundle: Some(false), + whole_archive: Some(false) | None, + } => { + cmd.link_staticlib(name, lib.verbatim.unwrap_or(false)); + } + NativeLibKind::LinkArg => { + cmd.arg(name); + } + NativeLibKind::Dylib { .. } + | NativeLibKind::Framework { .. } + | NativeLibKind::Unspecified + | NativeLibKind::RawDylib => {} + NativeLibKind::Static { + bundle: Some(true) | None, + whole_archive: _, + } => {} } } } @@ -2565,7 +2585,7 @@ fn add_upstream_native_libraries( // already included them in add_local_native_libraries and // add_upstream_rust_crates NativeLibKind::Static { .. } => {} - NativeLibKind::RawDylib => {} + NativeLibKind::RawDylib | NativeLibKind::LinkArg => {} } } } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 55307b9cebb70..0c3322a795377 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1942,9 +1942,22 @@ fn parse_native_lib_kind( "static" => NativeLibKind::Static { bundle: None, whole_archive: None }, "dylib" => NativeLibKind::Dylib { as_needed: None }, "framework" => NativeLibKind::Framework { as_needed: None }, + "link-arg" => { + if !nightly_options::is_unstable_enabled(matches) { + let why = if nightly_options::match_is_nightly_build(matches) { + " and only accepted on the nightly compiler" + } else { + ", the `-Z unstable-options` flag must also be passed to use it" + }; + early_error(error_format, &format!("library kind `link-arg` is unstable{why}")) + } + NativeLibKind::LinkArg + } _ => early_error( error_format, - &format!("unknown library kind `{kind}`, expected one of: static, dylib, framework"), + &format!( + "unknown library kind `{kind}`, expected one of: static, dylib, framework, link-arg" + ), ), }; match modifiers { @@ -2043,7 +2056,7 @@ fn parse_libs(matches: &getopts::Matches, error_format: ErrorOutputType) -> Vec< .into_iter() .map(|s| { // Parse string of the form "[KIND[:MODIFIERS]=]lib[:new_name]", - // where KIND is one of "dylib", "framework", "static" and + // where KIND is one of "dylib", "framework", "static", "link-arg" and // where MODIFIERS are a comma separated list of supported modifiers // (bundle, verbatim, whole-archive, as-needed). Each modifier is prefixed // with either + or - to indicate whether it is enabled or disabled. diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs index bda7b314308a5..9a4f6f9f9ef0c 100644 --- a/compiler/rustc_session/src/utils.rs +++ b/compiler/rustc_session/src/utils.rs @@ -34,6 +34,9 @@ pub enum NativeLibKind { /// Whether the framework will be linked only if it satisfies some undefined symbols as_needed: Option, }, + /// Argument which is passed to linker, relative order with libraries and other arguments + /// is preserved + LinkArg, /// The library kind wasn't specified, `Dylib` is currently used as a default. Unspecified, } @@ -47,7 +50,7 @@ impl NativeLibKind { NativeLibKind::Dylib { as_needed } | NativeLibKind::Framework { as_needed } => { as_needed.is_some() } - NativeLibKind::RawDylib | NativeLibKind::Unspecified => false, + NativeLibKind::RawDylib | NativeLibKind::Unspecified | NativeLibKind::LinkArg => false, } } } diff --git a/compiler/rustc_target/src/spec/thumbv6m_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv6m_none_eabi.rs index 2546ab9b7e680..dffa19ae55c04 100644 --- a/compiler/rustc_target/src/spec/thumbv6m_none_eabi.rs +++ b/compiler/rustc_target/src/spec/thumbv6m_none_eabi.rs @@ -14,8 +14,9 @@ pub fn target() -> Target { // The ARMv6-M architecture doesn't support unaligned loads/stores so we disable them // with +strict-align. features: "+strict-align".into(), - // There are no atomic CAS instructions available in the instruction set of the ARMv6-M + // There are no atomic instructions available in the instruction set of the ARMv6-M // architecture + max_atomic_width: Some(0), atomic_cas: false, ..super::thumb_base::opts() }, diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index e6284b1c4ace0..decbf0133114f 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -185,14 +185,20 @@ pub fn is_const_evaluatable<'cx, 'tcx>( } let concrete = infcx.const_eval_resolve(param_env, uv.expand(), Some(span)); match concrete { - Err(ErrorHandled::TooGeneric) => Err(if !uv.has_infer_types_or_consts() { + Err(ErrorHandled::TooGeneric) => Err(if uv.has_infer_types_or_consts() { + NotConstEvaluatable::MentionsInfer + } else if uv.has_param_types_or_consts() { infcx .tcx .sess .delay_span_bug(span, &format!("unexpected `TooGeneric` for {:?}", uv)); NotConstEvaluatable::MentionsParam } else { - NotConstEvaluatable::MentionsInfer + let guar = infcx.tcx.sess.delay_span_bug( + span, + format!("Missing value for constant, but no error reported?"), + ); + NotConstEvaluatable::Error(guar) }), Err(ErrorHandled::Linted) => { let reported = infcx @@ -240,8 +246,11 @@ pub fn is_const_evaluatable<'cx, 'tcx>( Err(ErrorHandled::TooGeneric) => Err(if uv.has_infer_types_or_consts() { NotConstEvaluatable::MentionsInfer - } else { + } else if uv.has_param_types_or_consts() { NotConstEvaluatable::MentionsParam + } else { + let guar = infcx.tcx.sess.delay_span_bug(span, format!("Missing value for constant, but no error reported?")); + NotConstEvaluatable::Error(guar) }), Err(ErrorHandled::Linted) => { let reported = diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 5e58f2379827e..979e997f24491 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -280,6 +280,11 @@ fn resolve_associated_item<'tcx>( return Ok(None); } + // If the item does not have a value, then we cannot return an instance. + if !leaf_def.item.defaultness.has_value() { + return Ok(None); + } + let substs = tcx.erase_regions(substs); // Check if we just resolved an associated `const` declaration from diff --git a/library/test/src/console.rs b/library/test/src/console.rs index dc0123cf43266..e9dda98966de3 100644 --- a/library/test/src/console.rs +++ b/library/test/src/console.rs @@ -137,7 +137,7 @@ impl ConsoleTestState { // List the tests to console, and optionally to logfile. Filters are honored. pub fn list_tests_console(opts: &TestOpts, tests: Vec) -> io::Result<()> { let mut output = match term::stdout() { - None => OutputLocation::Raw(io::stdout()), + None => OutputLocation::Raw(io::stdout().lock()), Some(t) => OutputLocation::Pretty(t), }; diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index e6f006135e29a..c43fd1ad24173 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -121,7 +121,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { unsafety: hir::Unsafety::Normal, generics: new_generics, trait_: Some(trait_ref.clean(self.cx)), - for_: ty.clean(self.cx), + for_: clean_middle_ty(ty, self.cx, None), items: Vec::new(), polarity, kind: ImplKind::Auto, diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 12137667e7bf8..c64c5895079be 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -116,14 +116,14 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { // FIXME(eddyb) compute both `trait_` and `for_` from // the post-inference `trait_ref`, as it's more accurate. trait_: Some(trait_ref.0.clean(cx)), - for_: ty.0.clean(cx), + for_: clean_middle_ty(ty.0, cx, None), items: cx.tcx .associated_items(impl_def_id) .in_definition_order() .map(|x| x.clean(cx)) .collect::>(), polarity: ty::ImplPolarity::Positive, - kind: ImplKind::Blanket(Box::new(trait_ref.0.self_ty().clean(cx))), + kind: ImplKind::Blanket(Box::new(clean_middle_ty(trait_ref.0.self_ty(), cx, None))), })), cfg: None, }); diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 6b37b8e4db46e..7a4ec889ac757 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -16,8 +16,8 @@ use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; use crate::clean::{ - self, clean_fn_decl_from_did_and_sig, clean_ty_generics, utils, Attributes, AttributesExt, - Clean, ImplKind, ItemId, Type, Visibility, + self, clean_fn_decl_from_did_and_sig, clean_middle_ty, clean_ty, clean_ty_generics, utils, + Attributes, AttributesExt, Clean, ImplKind, ItemId, Type, Visibility, }; use crate::core::DocContext; use crate::formats::item_type::ItemType; @@ -261,7 +261,7 @@ fn build_union(cx: &mut DocContext<'_>, did: DefId) -> clean::Union { fn build_type_alias(cx: &mut DocContext<'_>, did: DefId) -> clean::Typedef { let predicates = cx.tcx.explicit_predicates_of(did); - let type_ = cx.tcx.type_of(did).clean(cx); + let type_ = clean_middle_ty(cx.tcx.type_of(did), cx, Some(did)); clean::Typedef { type_, @@ -357,8 +357,8 @@ pub(crate) fn build_impl( }; let for_ = match &impl_item { - Some(impl_) => impl_.self_ty.clean(cx), - None => tcx.type_of(did).clean(cx), + Some(impl_) => clean_ty(impl_.self_ty, cx), + None => clean_middle_ty(tcx.type_of(did), cx, Some(did)), }; // Only inline impl if the implementing type is @@ -577,14 +577,14 @@ pub(crate) fn print_inlined_const(tcx: TyCtxt<'_>, did: DefId) -> String { fn build_const(cx: &mut DocContext<'_>, def_id: DefId) -> clean::Constant { clean::Constant { - type_: cx.tcx.type_of(def_id).clean(cx), + type_: clean_middle_ty(cx.tcx.type_of(def_id), cx, Some(def_id)), kind: clean::ConstantKind::Extern { def_id }, } } fn build_static(cx: &mut DocContext<'_>, did: DefId, mutable: bool) -> clean::Static { clean::Static { - type_: cx.tcx.type_of(did).clean(cx), + type_: clean_middle_ty(cx.tcx.type_of(did), cx, Some(did)), mutability: if mutable { Mutability::Mut } else { Mutability::Not }, expr: None, } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 43ebaab98db60..6160783f652f1 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -239,11 +239,9 @@ impl<'tcx> Clean<'tcx, Lifetime> for hir::Lifetime { impl<'tcx> Clean<'tcx, Constant> for hir::ConstArg { fn clean(&self, cx: &mut DocContext<'tcx>) -> Constant { + let def_id = cx.tcx.hir().body_owner_def_id(self.value.body).to_def_id(); Constant { - type_: cx - .tcx - .type_of(cx.tcx.hir().body_owner_def_id(self.value.body).to_def_id()) - .clean(cx), + type_: clean_middle_ty(cx.tcx.type_of(def_id), cx, Some(def_id)), kind: ConstantKind::Anonymous { body: self.value.body }, } } @@ -297,7 +295,7 @@ impl<'tcx> Clean<'tcx, Option> for hir::WherePredicate<'tcx> { }) .collect(); WherePredicate::BoundPredicate { - ty: wbp.bounded_ty.clean(cx), + ty: clean_ty(wbp.bounded_ty, cx), bounds: wbp.bounds.iter().filter_map(|x| x.clean(cx)).collect(), bound_params, } @@ -309,8 +307,8 @@ impl<'tcx> Clean<'tcx, Option> for hir::WherePredicate<'tcx> { }, hir::WherePredicate::EqPredicate(ref wrp) => WherePredicate::EqPredicate { - lhs: wrp.lhs_ty.clean(cx), - rhs: wrp.rhs_ty.clean(cx).into(), + lhs: clean_ty(wrp.lhs_ty, cx), + rhs: clean_ty(wrp.rhs_ty, cx).into(), }, }) } @@ -348,7 +346,7 @@ impl<'tcx> Clean<'tcx, Option> for ty::PolyTraitPredicate<'tcx> let poly_trait_ref = self.map_bound(|pred| pred.trait_ref); Some(WherePredicate::BoundPredicate { - ty: poly_trait_ref.skip_binder().self_ty().clean(cx), + ty: clean_middle_ty(poly_trait_ref.skip_binder().self_ty(), cx, None), bounds: vec![poly_trait_ref.clean(cx)], bound_params: Vec::new(), }) @@ -383,7 +381,7 @@ impl<'tcx> Clean<'tcx, Option> } Some(WherePredicate::BoundPredicate { - ty: ty.clean(cx), + ty: clean_middle_ty(*ty, cx, None), bounds: vec![GenericBound::Outlives(lt.clean(cx).expect("failed to clean lifetimes"))], bound_params: Vec::new(), }) @@ -393,7 +391,7 @@ impl<'tcx> Clean<'tcx, Option> impl<'tcx> Clean<'tcx, Term> for ty::Term<'tcx> { fn clean(&self, cx: &mut DocContext<'tcx>) -> Term { match self { - ty::Term::Ty(ty) => Term::Type(ty.clean(cx)), + ty::Term::Ty(ty) => Term::Type(clean_middle_ty(*ty, cx, None)), ty::Term::Const(c) => Term::Constant(c.clean(cx)), } } @@ -402,7 +400,7 @@ impl<'tcx> Clean<'tcx, Term> for ty::Term<'tcx> { impl<'tcx> Clean<'tcx, Term> for hir::Term<'tcx> { fn clean(&self, cx: &mut DocContext<'tcx>) -> Term { match self { - hir::Term::Ty(ty) => Term::Type(ty.clean(cx)), + hir::Term::Ty(ty) => Term::Type(clean_ty(ty, cx)), hir::Term::Const(c) => { let def_id = cx.tcx.hir().local_def_id(c.hir_id); Term::Constant(ty::Const::from_anon_const(cx.tcx, def_id).clean(cx)) @@ -425,7 +423,7 @@ fn clean_projection<'tcx>( ) -> Type { let lifted = ty.lift_to_tcx(cx.tcx).unwrap(); let trait_ = lifted.trait_ref(cx.tcx).clean(cx); - let self_type = ty.self_ty().clean(cx); + let self_type = clean_middle_ty(ty.self_ty(), cx, None); let self_def_id = if let Some(def_id) = def_id { cx.tcx.opt_parent(def_id).or(Some(def_id)) } else { @@ -476,7 +474,7 @@ impl<'tcx> Clean<'tcx, GenericParamDef> for ty::GenericParamDef { } ty::GenericParamDefKind::Type { has_default, synthetic, .. } => { let default = if has_default { - Some(clean_ty(cx.tcx.type_of(self.def_id), cx, Some(self.def_id))) + Some(clean_middle_ty(cx.tcx.type_of(self.def_id), cx, Some(self.def_id))) } else { None }; @@ -494,7 +492,11 @@ impl<'tcx> Clean<'tcx, GenericParamDef> for ty::GenericParamDef { self.name, GenericParamDefKind::Const { did: self.def_id, - ty: Box::new(cx.tcx.type_of(self.def_id).clean(cx)), + ty: Box::new(clean_middle_ty( + cx.tcx.type_of(self.def_id), + cx, + Some(self.def_id), + )), default: match has_default { true => Some(Box::new(cx.tcx.const_param_default(self.def_id).to_string())), false => None, @@ -546,7 +548,7 @@ fn clean_generic_param<'tcx>( GenericParamDefKind::Type { did: did.to_def_id(), bounds, - default: default.map(|t| t.clean(cx)).map(Box::new), + default: default.map(|t| clean_ty(t, cx)).map(Box::new), synthetic, }, ) @@ -555,7 +557,7 @@ fn clean_generic_param<'tcx>( param.name.ident().name, GenericParamDefKind::Const { did: did.to_def_id(), - ty: Box::new(ty.clean(cx)), + ty: Box::new(clean_ty(ty, cx)), default: default.map(|ct| { let def_id = cx.tcx.hir().local_def_id(ct.hir_id); Box::new(ty::Const::from_anon_const(cx.tcx, def_id).to_string()) @@ -752,7 +754,7 @@ fn clean_ty_generics<'tcx>( if let crate::core::ImplTraitParam::ParamIndex(idx) = param { if let Some(proj) = impl_trait_proj.remove(&idx) { for (trait_did, name, rhs) in proj { - let rhs = rhs.clean(cx); + let rhs = clean_middle_ty(rhs, cx, None); simplify::merge_bounds(cx, &mut bounds, trait_did, name, &Term::Type(rhs)); } } @@ -926,7 +928,7 @@ fn clean_args_from_types_and_names<'tcx>( if name.is_empty() { name = kw::Underscore; } - Argument { name, type_: ty.clean(cx), is_const: false } + Argument { name, type_: clean_ty(ty, cx), is_const: false } }) .collect(), } @@ -945,7 +947,7 @@ fn clean_args_from_types_and_body_id<'tcx>( .enumerate() .map(|(i, ty)| Argument { name: name_from_pat(body.params[i].pat), - type_: ty.clean(cx), + type_: clean_ty(ty, cx), is_const: false, }) .collect(), @@ -969,7 +971,7 @@ fn clean_fn_decl_from_did_and_sig<'tcx>( // We assume all empty tuples are default return type. This theoretically can discard `-> ()`, // but shouldn't change any code meaning. - let output = match sig.skip_binder().output().clean(cx) { + let output = match clean_middle_ty(sig.skip_binder().output(), cx, None) { Type::Tuple(inner) if inner.is_empty() => DefaultReturn, ty => Return(ty), }; @@ -983,7 +985,7 @@ fn clean_fn_decl_from_did_and_sig<'tcx>( .inputs() .iter() .map(|t| Argument { - type_: t.clean(cx), + type_: clean_middle_ty(*t, cx, None), name: names.next().map_or(kw::Empty, |i| i.name), is_const: false, }) @@ -995,7 +997,7 @@ fn clean_fn_decl_from_did_and_sig<'tcx>( impl<'tcx> Clean<'tcx, FnRetTy> for hir::FnRetTy<'tcx> { fn clean(&self, cx: &mut DocContext<'tcx>) -> FnRetTy { match *self { - Self::Return(typ) => Return(typ.clean(cx)), + Self::Return(typ) => Return(clean_ty(typ, cx)), Self::DefaultReturn(..) => DefaultReturn, } } @@ -1038,10 +1040,10 @@ impl<'tcx> Clean<'tcx, Item> for hir::TraitItem<'tcx> { cx.with_param_env(local_did, |cx| { let inner = match self.kind { hir::TraitItemKind::Const(ty, Some(default)) => AssocConstItem( - ty.clean(cx), + clean_ty(ty, cx), ConstantKind::Local { def_id: local_did, body: default }, ), - hir::TraitItemKind::Const(ty, None) => TyAssocConstItem(ty.clean(cx)), + hir::TraitItemKind::Const(ty, None) => TyAssocConstItem(clean_ty(ty, cx)), hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => { let m = clean_function(cx, sig, self.generics, body); MethodItem(m, None) @@ -1059,9 +1061,13 @@ impl<'tcx> Clean<'tcx, Item> for hir::TraitItem<'tcx> { hir::TraitItemKind::Type(bounds, Some(default)) => { let generics = enter_impl_trait(cx, |cx| self.generics.clean(cx)); let bounds = bounds.iter().filter_map(|x| x.clean(cx)).collect(); - let item_type = hir_ty_to_ty(cx.tcx, default).clean(cx); + let item_type = clean_middle_ty(hir_ty_to_ty(cx.tcx, default), cx, None); AssocTypeItem( - Typedef { type_: default.clean(cx), generics, item_type: Some(item_type) }, + Typedef { + type_: clean_ty(default, cx), + generics, + item_type: Some(item_type), + }, bounds, ) } @@ -1086,7 +1092,7 @@ impl<'tcx> Clean<'tcx, Item> for hir::ImplItem<'tcx> { let inner = match self.kind { hir::ImplItemKind::Const(ty, expr) => { let default = ConstantKind::Local { def_id: local_did, body: expr }; - AssocConstItem(ty.clean(cx), default) + AssocConstItem(clean_ty(ty, cx), default) } hir::ImplItemKind::Fn(ref sig, body) => { let m = clean_function(cx, sig, self.generics, body); @@ -1094,9 +1100,9 @@ impl<'tcx> Clean<'tcx, Item> for hir::ImplItem<'tcx> { MethodItem(m, Some(defaultness)) } hir::ImplItemKind::TyAlias(hir_ty) => { - let type_ = hir_ty.clean(cx); + let type_ = clean_ty(hir_ty, cx); let generics = self.generics.clean(cx); - let item_type = hir_ty_to_ty(cx.tcx, hir_ty).clean(cx); + let item_type = clean_middle_ty(hir_ty_to_ty(cx.tcx, hir_ty), cx, None); AssocTypeItem( Typedef { type_, generics, item_type: Some(item_type) }, Vec::new(), @@ -1125,7 +1131,7 @@ impl<'tcx> Clean<'tcx, Item> for ty::AssocItem { let tcx = cx.tcx; let kind = match self.kind { ty::AssocKind::Const => { - let ty = tcx.type_of(self.def_id).clean(cx); + let ty = clean_middle_ty(tcx.type_of(self.def_id), cx, Some(self.def_id)); let provided = match self.container { ty::ImplContainer(_) => true, @@ -1272,7 +1278,11 @@ impl<'tcx> Clean<'tcx, Item> for ty::AssocItem { if self.defaultness.has_value() { AssocTypeItem( Typedef { - type_: tcx.type_of(self.def_id).clean(cx), + type_: clean_middle_ty( + tcx.type_of(self.def_id), + cx, + Some(self.def_id), + ), generics, // FIXME: should we obtain the Type from HIR and pass it on here? item_type: None, @@ -1286,7 +1296,7 @@ impl<'tcx> Clean<'tcx, Item> for ty::AssocItem { // FIXME: when could this happen? Associated items in inherent impls? AssocTypeItem( Typedef { - type_: tcx.type_of(self.def_id).clean(cx), + type_: clean_middle_ty(tcx.type_of(self.def_id), cx, Some(self.def_id)), generics: Generics { params: Vec::new(), where_predicates: Vec::new() }, item_type: None, }, @@ -1337,7 +1347,7 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type // Try to normalize `::T` to a type let ty = hir_ty_to_ty(cx.tcx, hir_ty); if let Some(normalized_value) = normalize(cx, ty) { - return normalized_value.clean(cx); + return clean_middle_ty(normalized_value, cx, None); } let trait_segments = &p.segments[..p.segments.len() - 1]; @@ -1348,7 +1358,7 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type }; register_res(cx, trait_.res); let self_def_id = DefId::local(qself.hir_id.owner.local_def_index); - let self_type = qself.clean(cx); + let self_type = clean_ty(qself, cx); let should_show_cast = compute_should_show_cast(Some(self_def_id), &trait_, &self_type); Type::QPath { assoc: Box::new(p.segments.last().expect("segments were empty").clean(cx)), @@ -1368,7 +1378,7 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type let trait_ = hir::Path { span, res, segments: &[] }.clean(cx); register_res(cx, trait_.res); let self_def_id = res.opt_def_id(); - let self_type = qself.clean(cx); + let self_type = clean_ty(qself, cx); let should_show_cast = compute_should_show_cast(self_def_id, &trait_, &self_type); Type::QPath { assoc: Box::new(segment.clean(cx)), @@ -1435,9 +1445,12 @@ fn maybe_expand_private_type_alias<'tcx>( _ => None, }); if let Some(ty) = type_ { - substs.insert(ty_param_def_id.to_def_id(), SubstParam::Type(ty.clean(cx))); + substs.insert(ty_param_def_id.to_def_id(), SubstParam::Type(clean_ty(ty, cx))); } else if let Some(default) = *default { - substs.insert(ty_param_def_id.to_def_id(), SubstParam::Type(default.clean(cx))); + substs.insert( + ty_param_def_id.to_def_id(), + SubstParam::Type(clean_ty(default, cx)), + ); } indices.types += 1; } @@ -1464,70 +1477,68 @@ fn maybe_expand_private_type_alias<'tcx>( } } - Some(cx.enter_alias(substs, |cx| ty.clean(cx))) + Some(cx.enter_alias(substs, |cx| clean_ty(ty, cx))) } -impl<'tcx> Clean<'tcx, Type> for hir::Ty<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Type { - use rustc_hir::*; - - match self.kind { - TyKind::Never => Primitive(PrimitiveType::Never), - TyKind::Ptr(ref m) => RawPointer(m.mutbl, Box::new(m.ty.clean(cx))), - TyKind::Rptr(ref l, ref m) => { - // There are two times a `Fresh` lifetime can be created: - // 1. For `&'_ x`, written by the user. This corresponds to `lower_lifetime` in `rustc_ast_lowering`. - // 2. For `&x` as a parameter to an `async fn`. This corresponds to `elided_ref_lifetime in `rustc_ast_lowering`. - // See #59286 for more information. - // Ideally we would only hide the `'_` for case 2., but I don't know a way to distinguish it. - // Turning `fn f(&'_ self)` into `fn f(&self)` isn't the worst thing in the world, though; - // there's no case where it could cause the function to fail to compile. - let elided = - l.is_elided() || matches!(l.name, LifetimeName::Param(_, ParamName::Fresh)); - let lifetime = if elided { None } else { Some(l.clean(cx)) }; - BorrowedRef { lifetime, mutability: m.mutbl, type_: Box::new(m.ty.clean(cx)) } - } - TyKind::Slice(ty) => Slice(Box::new(ty.clean(cx))), - TyKind::Array(ty, ref length) => { - let length = match length { - hir::ArrayLen::Infer(_, _) => "_".to_string(), - hir::ArrayLen::Body(anon_const) => { - let def_id = cx.tcx.hir().local_def_id(anon_const.hir_id); - // NOTE(min_const_generics): We can't use `const_eval_poly` for constants - // as we currently do not supply the parent generics to anonymous constants - // but do allow `ConstKind::Param`. - // - // `const_eval_poly` tries to to first substitute generic parameters which - // results in an ICE while manually constructing the constant and using `eval` - // does nothing for `ConstKind::Param`. - let ct = ty::Const::from_anon_const(cx.tcx, def_id); - let param_env = cx.tcx.param_env(def_id); - print_const(cx, ct.eval(cx.tcx, param_env)) - } - }; +pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type { + use rustc_hir::*; - Array(Box::new(ty.clean(cx)), length) - } - TyKind::Tup(tys) => Tuple(tys.iter().map(|x| x.clean(cx)).collect()), - TyKind::OpaqueDef(item_id, _) => { - let item = cx.tcx.hir().item(item_id); - if let hir::ItemKind::OpaqueTy(ref ty) = item.kind { - ImplTrait(ty.bounds.iter().filter_map(|x| x.clean(cx)).collect()) - } else { - unreachable!() + match ty.kind { + TyKind::Never => Primitive(PrimitiveType::Never), + TyKind::Ptr(ref m) => RawPointer(m.mutbl, Box::new(clean_ty(m.ty, cx))), + TyKind::Rptr(ref l, ref m) => { + // There are two times a `Fresh` lifetime can be created: + // 1. For `&'_ x`, written by the user. This corresponds to `lower_lifetime` in `rustc_ast_lowering`. + // 2. For `&x` as a parameter to an `async fn`. This corresponds to `elided_ref_lifetime in `rustc_ast_lowering`. + // See #59286 for more information. + // Ideally we would only hide the `'_` for case 2., but I don't know a way to distinguish it. + // Turning `fn f(&'_ self)` into `fn f(&self)` isn't the worst thing in the world, though; + // there's no case where it could cause the function to fail to compile. + let elided = + l.is_elided() || matches!(l.name, LifetimeName::Param(_, ParamName::Fresh)); + let lifetime = if elided { None } else { Some(l.clean(cx)) }; + BorrowedRef { lifetime, mutability: m.mutbl, type_: Box::new(clean_ty(m.ty, cx)) } + } + TyKind::Slice(ty) => Slice(Box::new(clean_ty(ty, cx))), + TyKind::Array(ty, ref length) => { + let length = match length { + hir::ArrayLen::Infer(_, _) => "_".to_string(), + hir::ArrayLen::Body(anon_const) => { + let def_id = cx.tcx.hir().local_def_id(anon_const.hir_id); + // NOTE(min_const_generics): We can't use `const_eval_poly` for constants + // as we currently do not supply the parent generics to anonymous constants + // but do allow `ConstKind::Param`. + // + // `const_eval_poly` tries to to first substitute generic parameters which + // results in an ICE while manually constructing the constant and using `eval` + // does nothing for `ConstKind::Param`. + let ct = ty::Const::from_anon_const(cx.tcx, def_id); + let param_env = cx.tcx.param_env(def_id); + print_const(cx, ct.eval(cx.tcx, param_env)) } + }; + + Array(Box::new(clean_ty(ty, cx)), length) + } + TyKind::Tup(tys) => Tuple(tys.iter().map(|ty| clean_ty(ty, cx)).collect()), + TyKind::OpaqueDef(item_id, _) => { + let item = cx.tcx.hir().item(item_id); + if let hir::ItemKind::OpaqueTy(ref ty) = item.kind { + ImplTrait(ty.bounds.iter().filter_map(|x| x.clean(cx)).collect()) + } else { + unreachable!() } - TyKind::Path(_) => clean_qpath(self, cx), - TyKind::TraitObject(bounds, ref lifetime, _) => { - let bounds = bounds.iter().map(|bound| bound.clean(cx)).collect(); - let lifetime = if !lifetime.is_elided() { Some(lifetime.clean(cx)) } else { None }; - DynTrait(bounds, lifetime) - } - TyKind::BareFn(barefn) => BareFunction(Box::new(barefn.clean(cx))), - // Rustdoc handles `TyKind::Err`s by turning them into `Type::Infer`s. - TyKind::Infer | TyKind::Err => Infer, - TyKind::Typeof(..) => panic!("unimplemented type {:?}", self.kind), } + TyKind::Path(_) => clean_qpath(ty, cx), + TyKind::TraitObject(bounds, ref lifetime, _) => { + let bounds = bounds.iter().map(|bound| bound.clean(cx)).collect(); + let lifetime = if !lifetime.is_elided() { Some(lifetime.clean(cx)) } else { None }; + DynTrait(bounds, lifetime) + } + TyKind::BareFn(barefn) => BareFunction(Box::new(barefn.clean(cx))), + // Rustdoc handles `TyKind::Err`s by turning them into `Type::Infer`s. + TyKind::Infer | TyKind::Err => Infer, + TyKind::Typeof(..) => panic!("unimplemented type {:?}", ty.kind), } } @@ -1562,7 +1573,11 @@ fn normalize<'tcx>(cx: &mut DocContext<'tcx>, ty: Ty<'_>) -> Option> { } } -fn clean_ty<'tcx>(this: Ty<'tcx>, cx: &mut DocContext<'tcx>, def_id: Option) -> Type { +pub(crate) fn clean_middle_ty<'tcx>( + this: Ty<'tcx>, + cx: &mut DocContext<'tcx>, + def_id: Option, +) -> Type { trace!("cleaning type: {:?}", this); let ty = normalize(cx, this).unwrap_or(this); match *ty.kind() { @@ -1573,17 +1588,19 @@ fn clean_ty<'tcx>(this: Ty<'tcx>, cx: &mut DocContext<'tcx>, def_id: Option Primitive(uint_ty.into()), ty::Float(float_ty) => Primitive(float_ty.into()), ty::Str => Primitive(PrimitiveType::Str), - ty::Slice(ty) => Slice(Box::new(ty.clean(cx))), + ty::Slice(ty) => Slice(Box::new(clean_middle_ty(ty, cx, None))), ty::Array(ty, n) => { let mut n = cx.tcx.lift(n).expect("array lift failed"); n = n.eval(cx.tcx, ty::ParamEnv::reveal_all()); let n = print_const(cx, n); - Array(Box::new(ty.clean(cx)), n) - } - ty::RawPtr(mt) => RawPointer(mt.mutbl, Box::new(mt.ty.clean(cx))), - ty::Ref(r, ty, mutbl) => { - BorrowedRef { lifetime: r.clean(cx), mutability: mutbl, type_: Box::new(ty.clean(cx)) } + Array(Box::new(clean_middle_ty(ty, cx, None)), n) } + ty::RawPtr(mt) => RawPointer(mt.mutbl, Box::new(clean_middle_ty(mt.ty, cx, None))), + ty::Ref(r, ty, mutbl) => BorrowedRef { + lifetime: r.clean(cx), + mutability: mutbl, + type_: Box::new(clean_middle_ty(ty, cx, None)), + }, ty::FnDef(..) | ty::FnPtr(_) => { let ty = cx.tcx.lift(this).expect("FnPtr lift failed"); let sig = ty.fn_sig(cx.tcx); @@ -1660,7 +1677,7 @@ fn clean_ty<'tcx>(this: Ty<'tcx>, cx: &mut DocContext<'tcx>, def_id: Option Tuple(t.iter().map(|t| t.clean(cx)).collect()), + ty::Tuple(t) => Tuple(t.iter().map(|t| clean_middle_ty(t, cx, None)).collect()), ty::Projection(ref data) => clean_projection(*data, cx, def_id), @@ -1747,17 +1764,11 @@ fn clean_ty<'tcx>(this: Ty<'tcx>, cx: &mut DocContext<'tcx>, def_id: Option Clean<'tcx, Type> for Ty<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Type { - clean_ty(*self, cx, None) - } -} - impl<'tcx> Clean<'tcx, Constant> for ty::Const<'tcx> { fn clean(&self, cx: &mut DocContext<'tcx>) -> Constant { // FIXME: instead of storing the stringified expression, store `self` directly instead. Constant { - type_: self.ty().clean(cx), + type_: clean_middle_ty(self.ty(), cx, None), kind: ConstantKind::TyConst { expr: self.to_string() }, } } @@ -1766,13 +1777,18 @@ impl<'tcx> Clean<'tcx, Constant> for ty::Const<'tcx> { impl<'tcx> Clean<'tcx, Item> for hir::FieldDef<'tcx> { fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { let def_id = cx.tcx.hir().local_def_id(self.hir_id).to_def_id(); - clean_field(def_id, self.ident.name, self.ty.clean(cx), cx) + clean_field(def_id, self.ident.name, clean_ty(self.ty, cx), cx) } } impl<'tcx> Clean<'tcx, Item> for ty::FieldDef { fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { - clean_field(self.did, self.name, cx.tcx.type_of(self.did).clean(cx), cx) + clean_field( + self.did, + self.name, + clean_middle_ty(cx.tcx.type_of(self.did), cx, Some(self.did)), + cx, + ) } } @@ -1863,10 +1879,10 @@ impl<'tcx> Clean<'tcx, Path> for hir::Path<'tcx> { impl<'tcx> Clean<'tcx, GenericArgs> for hir::GenericArgs<'tcx> { fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericArgs { if self.parenthesized { - let output = self.bindings[0].ty().clean(cx); + let output = clean_ty(self.bindings[0].ty(), cx); let output = if output != Type::Tuple(Vec::new()) { Some(Box::new(output)) } else { None }; - let inputs = self.inputs().iter().map(|x| x.clean(cx)).collect::>().into(); + let inputs = self.inputs().iter().map(|x| clean_ty(x, cx)).collect::>().into(); GenericArgs::Parenthesized { inputs, output } } else { let args = self @@ -1877,7 +1893,7 @@ impl<'tcx> Clean<'tcx, GenericArgs> for hir::GenericArgs<'tcx> { GenericArg::Lifetime(lt.clean(cx)) } hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()), - hir::GenericArg::Type(ty) => GenericArg::Type(ty.clean(cx)), + hir::GenericArg::Type(ty) => GenericArg::Type(clean_ty(ty, cx)), hir::GenericArg::Const(ct) => GenericArg::Const(Box::new(ct.clean(cx))), hir::GenericArg::Infer(_inf) => GenericArg::Infer, }) @@ -1925,10 +1941,10 @@ fn clean_maybe_renamed_item<'tcx>( cx.with_param_env(def_id, |cx| { let kind = match item.kind { ItemKind::Static(ty, mutability, body_id) => { - StaticItem(Static { type_: ty.clean(cx), mutability, expr: Some(body_id) }) + StaticItem(Static { type_: clean_ty(ty, cx), mutability, expr: Some(body_id) }) } ItemKind::Const(ty, body_id) => ConstantItem(Constant { - type_: ty.clean(cx), + type_: clean_ty(ty, cx), kind: ConstantKind::Local { body: body_id, def_id }, }), ItemKind::OpaqueTy(ref ty) => OpaqueTyItem(OpaqueTy { @@ -1936,8 +1952,8 @@ fn clean_maybe_renamed_item<'tcx>( generics: ty.generics.clean(cx), }), ItemKind::TyAlias(hir_ty, generics) => { - let rustdoc_ty = hir_ty.clean(cx); - let ty = hir_ty_to_ty(cx.tcx, hir_ty).clean(cx); + let rustdoc_ty = clean_ty(hir_ty, cx); + let ty = clean_middle_ty(hir_ty_to_ty(cx.tcx, hir_ty), cx, None); TypedefItem(Typedef { type_: rustdoc_ty, generics: generics.clean(cx), @@ -2023,9 +2039,9 @@ fn clean_impl<'tcx>( build_deref_target_impls(cx, &items, &mut ret); } - let for_ = impl_.self_ty.clean(cx); + let for_ = clean_ty(impl_.self_ty, cx); let type_alias = for_.def_id(&cx.cache).and_then(|did| match tcx.def_kind(did) { - DefKind::TyAlias => Some(tcx.type_of(did).clean(cx)), + DefKind::TyAlias => Some(clean_middle_ty(tcx.type_of(did), cx, Some(did))), _ => None, }); let mut make_item = |trait_: Option, for_: Type, items: Vec| { @@ -2234,7 +2250,7 @@ fn clean_maybe_renamed_foreign_item<'tcx>( ForeignFunctionItem(Function { decl, generics }) } hir::ForeignItemKind::Static(ty, mutability) => { - ForeignStaticItem(Static { type_: ty.clean(cx), mutability, expr: None }) + ForeignStaticItem(Static { type_: clean_ty(ty, cx), mutability, expr: None }) } hir::ForeignItemKind::Type => ForeignTypeItem, }; diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index fa449a21b0c93..00d62b3748455 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -2,8 +2,9 @@ use crate::clean::auto_trait::AutoTraitFinder; use crate::clean::blanket_impl::BlanketImplFinder; use crate::clean::render_macro_matchers::render_macro_matcher; use crate::clean::{ - inline, Clean, Crate, ExternalCrate, Generic, GenericArg, GenericArgs, ImportSource, Item, - ItemKind, Lifetime, Path, PathSegment, Primitive, PrimitiveType, Type, TypeBinding, Visibility, + clean_middle_ty, inline, Clean, Crate, ExternalCrate, Generic, GenericArg, GenericArgs, + ImportSource, Item, ItemKind, Lifetime, Path, PathSegment, Primitive, PrimitiveType, Type, + TypeBinding, Visibility, }; use crate::core::DocContext; use crate::formats::item_type::ItemType; @@ -91,7 +92,7 @@ pub(crate) fn substs_to_args<'tcx>( skip_first = false; None } - GenericArgKind::Type(ty) => Some(GenericArg::Type(ty.clean(cx))), + GenericArgKind::Type(ty) => Some(GenericArg::Type(clean_middle_ty(ty, cx, None))), GenericArgKind::Const(ct) => Some(GenericArg::Const(Box::new(ct.clean(cx)))), })); ret_val @@ -110,7 +111,7 @@ fn external_generic_args<'tcx>( let inputs = // The trait's first substitution is the one after self, if there is one. match substs.iter().nth(if has_self { 1 } else { 0 }).unwrap().expect_ty().kind() { - ty::Tuple(tys) => tys.iter().map(|t| t.clean(cx)).collect::>().into(), + ty::Tuple(tys) => tys.iter().map(|t| clean_middle_ty(t, cx, None)).collect::>().into(), _ => return GenericArgs::AngleBracketed { args: args.into(), bindings: bindings.into() }, }; let output = None; diff --git a/src/test/run-make/pass-linker-flags-from-dep/Makefile b/src/test/run-make/pass-linker-flags-from-dep/Makefile new file mode 100644 index 0000000000000..eecd4a6e60757 --- /dev/null +++ b/src/test/run-make/pass-linker-flags-from-dep/Makefile @@ -0,0 +1,10 @@ +-include ../../run-make-fulldeps/tools.mk + +all: + # Build deps + $(RUSTC) native_dep_1.rs --crate-type=staticlib + $(RUSTC) native_dep_2.rs --crate-type=staticlib + $(RUSTC) rust_dep.rs -l static:-bundle=native_dep_1 -llink-arg=some_flag -l static:-bundle=native_dep_2 --crate-type=lib -Z unstable-options + + # Check sequence of linker args + $(RUSTC) main.rs --extern lib=$(TMPDIR)/librust_dep.rlib --crate-type=bin --print link-args | $(CGREP) -e '-lnative_dep_1.*some_flag.*-lnative_dep_2' diff --git a/src/test/run-make/pass-linker-flags-from-dep/main.rs b/src/test/run-make/pass-linker-flags-from-dep/main.rs new file mode 100644 index 0000000000000..87bd7a11fe52e --- /dev/null +++ b/src/test/run-make/pass-linker-flags-from-dep/main.rs @@ -0,0 +1,3 @@ +fn main() { + native_lib::f(); +} diff --git a/src/test/run-make/pass-linker-flags-from-dep/native_dep_1.rs b/src/test/run-make/pass-linker-flags-from-dep/native_dep_1.rs new file mode 100644 index 0000000000000..fdb2d9ca68e63 --- /dev/null +++ b/src/test/run-make/pass-linker-flags-from-dep/native_dep_1.rs @@ -0,0 +1 @@ +pub fn f1() {} diff --git a/src/test/run-make/pass-linker-flags-from-dep/native_dep_2.rs b/src/test/run-make/pass-linker-flags-from-dep/native_dep_2.rs new file mode 100644 index 0000000000000..f788b77118461 --- /dev/null +++ b/src/test/run-make/pass-linker-flags-from-dep/native_dep_2.rs @@ -0,0 +1 @@ +pub fn f2() {} diff --git a/src/test/run-make/pass-linker-flags-from-dep/rust_dep.rs b/src/test/run-make/pass-linker-flags-from-dep/rust_dep.rs new file mode 100644 index 0000000000000..7f5df1139342f --- /dev/null +++ b/src/test/run-make/pass-linker-flags-from-dep/rust_dep.rs @@ -0,0 +1,9 @@ +extern "C" { + pub fn foo(); +} + +pub fn f() { + unsafe { + foo(); + } +} diff --git a/src/test/run-make/pass-linker-flags/Makefile b/src/test/run-make/pass-linker-flags/Makefile new file mode 100644 index 0000000000000..c0be5fe2413a5 --- /dev/null +++ b/src/test/run-make/pass-linker-flags/Makefile @@ -0,0 +1,4 @@ +-include ../../run-make-fulldeps/tools.mk + +all: + $(RUSTC) rs.rs -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e '-ll1.*a1.*-ll2.*a2.*-ld1.*a3' diff --git a/src/test/run-make/pass-linker-flags/rs.rs b/src/test/run-make/pass-linker-flags/rs.rs new file mode 100644 index 0000000000000..f328e4d9d04c3 --- /dev/null +++ b/src/test/run-make/pass-linker-flags/rs.rs @@ -0,0 +1 @@ +fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-86530.rs b/src/test/ui/const-generics/issues/issue-86530.rs index 4a6ffd1f3008e..b024decd4e11c 100644 --- a/src/test/ui/const-generics/issues/issue-86530.rs +++ b/src/test/ui/const-generics/issues/issue-86530.rs @@ -15,7 +15,6 @@ where fn unit_literals() { z(" "); //~^ ERROR: the trait bound `&str: X` is not satisfied - //~| ERROR: unconstrained generic constant } fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-86530.stderr b/src/test/ui/const-generics/issues/issue-86530.stderr index c688f838dab47..c63857b2314e9 100644 --- a/src/test/ui/const-generics/issues/issue-86530.stderr +++ b/src/test/ui/const-generics/issues/issue-86530.stderr @@ -15,22 +15,6 @@ LL | where LL | T: X, | ^ required by this bound in `z` -error: unconstrained generic constant - --> $DIR/issue-86530.rs:16:5 - | -LL | z(" "); - | ^ - | - = help: try adding a `where` bound using this expression: `where [(); T::Y]:` -note: required by a bound in `z` - --> $DIR/issue-86530.rs:11:10 - | -LL | fn z(t: T) - | - required by a bound in this -... -LL | [(); T::Y]: , - | ^^^^ required by this bound in `z` - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/const-generics/issues/issue-98629.rs b/src/test/ui/const-generics/issues/issue-98629.rs new file mode 100644 index 0000000000000..fc8666bbcdb79 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-98629.rs @@ -0,0 +1,15 @@ +#![feature(const_trait_impl)] + +trait Trait { + const N: usize; +} + +impl const Trait for i32 {} +//~^ ERROR not all trait items implemented, missing: `N` + +fn f() +where + [(); ::N]:, +{} + +fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-98629.stderr b/src/test/ui/const-generics/issues/issue-98629.stderr new file mode 100644 index 0000000000000..53570220882c3 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-98629.stderr @@ -0,0 +1,12 @@ +error[E0046]: not all trait items implemented, missing: `N` + --> $DIR/issue-98629.rs:7:1 + | +LL | const N: usize; + | -------------- `N` from trait +... +LL | impl const Trait for i32 {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ missing `N` in implementation + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0046`. diff --git a/src/test/ui/issues/issue-77919.rs b/src/test/ui/issues/issue-77919.rs index 1d5d593073117..966d76d148af3 100644 --- a/src/test/ui/issues/issue-77919.rs +++ b/src/test/ui/issues/issue-77919.rs @@ -1,6 +1,5 @@ fn main() { [1; >::VAL]; - //~^ ERROR: constant expression depends on a generic parameter } trait TypeVal { const VAL: T; diff --git a/src/test/ui/issues/issue-77919.stderr b/src/test/ui/issues/issue-77919.stderr index b4c877a2d74a4..ca256847b1f3b 100644 --- a/src/test/ui/issues/issue-77919.stderr +++ b/src/test/ui/issues/issue-77919.stderr @@ -1,5 +1,5 @@ error[E0412]: cannot find type `PhantomData` in this scope - --> $DIR/issue-77919.rs:10:9 + --> $DIR/issue-77919.rs:9:9 | LL | _n: PhantomData, | ^^^^^^^^^^^ not found in this scope @@ -10,7 +10,7 @@ LL | use std::marker::PhantomData; | error[E0412]: cannot find type `VAL` in this scope - --> $DIR/issue-77919.rs:12:63 + --> $DIR/issue-77919.rs:11:63 | LL | impl TypeVal for Multiply where N: TypeVal {} | - ^^^ not found in this scope @@ -18,7 +18,7 @@ LL | impl TypeVal for Multiply where N: TypeVal {} | help: you might be missing a type parameter: `, VAL` error[E0046]: not all trait items implemented, missing: `VAL` - --> $DIR/issue-77919.rs:12:1 + --> $DIR/issue-77919.rs:11:1 | LL | const VAL: T; | ------------ `VAL` from trait @@ -26,15 +26,7 @@ LL | const VAL: T; LL | impl TypeVal for Multiply where N: TypeVal {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation -error: constant expression depends on a generic parameter - --> $DIR/issue-77919.rs:2:9 - | -LL | [1; >::VAL]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: this may fail depending on what value the parameter takes - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0046, E0412. For more information about an error, try `rustc --explain E0046`. diff --git a/src/test/ui/manual/manual-link-bad-kind.rs b/src/test/ui/manual/manual-link-bad-kind.rs index d1609338db666..c50a6c034b593 100644 --- a/src/test/ui/manual/manual-link-bad-kind.rs +++ b/src/test/ui/manual/manual-link-bad-kind.rs @@ -1,5 +1,5 @@ // compile-flags:-l bar=foo -// error-pattern: unknown library kind `bar`, expected one of: static, dylib, framework +// error-pattern: unknown library kind `bar`, expected one of: static, dylib, framework, link-arg fn main() { } diff --git a/src/test/ui/manual/manual-link-bad-kind.stderr b/src/test/ui/manual/manual-link-bad-kind.stderr index 86146956699f3..647c4c61e0212 100644 --- a/src/test/ui/manual/manual-link-bad-kind.stderr +++ b/src/test/ui/manual/manual-link-bad-kind.stderr @@ -1,2 +1,2 @@ -error: unknown library kind `bar`, expected one of: static, dylib, framework +error: unknown library kind `bar`, expected one of: static, dylib, framework, link-arg diff --git a/src/test/ui/manual/manual-link-unsupported-kind.rs b/src/test/ui/manual/manual-link-unsupported-kind.rs index 7a40186d504c6..b8ec575a455ff 100644 --- a/src/test/ui/manual/manual-link-unsupported-kind.rs +++ b/src/test/ui/manual/manual-link-unsupported-kind.rs @@ -1,5 +1,5 @@ // compile-flags:-l raw-dylib=foo -// error-pattern: unknown library kind `raw-dylib`, expected one of: static, dylib, framework +// error-pattern: unknown library kind `raw-dylib`, expected one of: static, dylib, framework, link-arg fn main() { } diff --git a/src/test/ui/manual/manual-link-unsupported-kind.stderr b/src/test/ui/manual/manual-link-unsupported-kind.stderr index 4965c0af5f241..ae4a1ec9a959b 100644 --- a/src/test/ui/manual/manual-link-unsupported-kind.stderr +++ b/src/test/ui/manual/manual-link-unsupported-kind.stderr @@ -1,2 +1,2 @@ -error: unknown library kind `raw-dylib`, expected one of: static, dylib, framework +error: unknown library kind `raw-dylib`, expected one of: static, dylib, framework, link-arg diff --git a/src/test/ui/native-library-link-flags/empty-kind-1.rs b/src/test/ui/native-library-link-flags/empty-kind-1.rs index 086d8cff95770..18937856d20d3 100644 --- a/src/test/ui/native-library-link-flags/empty-kind-1.rs +++ b/src/test/ui/native-library-link-flags/empty-kind-1.rs @@ -1,6 +1,6 @@ // Unspecified kind should fail with an error // compile-flags: -l =mylib -// error-pattern: unknown library kind ``, expected one of: static, dylib, framework +// error-pattern: unknown library kind ``, expected one of: static, dylib, framework, link-arg fn main() {} diff --git a/src/test/ui/native-library-link-flags/empty-kind-1.stderr b/src/test/ui/native-library-link-flags/empty-kind-1.stderr index 37846c0b06f69..3e5b054933999 100644 --- a/src/test/ui/native-library-link-flags/empty-kind-1.stderr +++ b/src/test/ui/native-library-link-flags/empty-kind-1.stderr @@ -1,2 +1,2 @@ -error: unknown library kind ``, expected one of: static, dylib, framework +error: unknown library kind ``, expected one of: static, dylib, framework, link-arg diff --git a/src/test/ui/native-library-link-flags/empty-kind-2.rs b/src/test/ui/native-library-link-flags/empty-kind-2.rs index 45ec8ec85e301..851eb63fcd8b8 100644 --- a/src/test/ui/native-library-link-flags/empty-kind-2.rs +++ b/src/test/ui/native-library-link-flags/empty-kind-2.rs @@ -1,6 +1,6 @@ // Unspecified kind should fail with an error // compile-flags: -l :+bundle=mylib -// error-pattern: unknown library kind ``, expected one of: static, dylib, framework +// error-pattern: unknown library kind ``, expected one of: static, dylib, framework, link-arg fn main() {} diff --git a/src/test/ui/native-library-link-flags/empty-kind-2.stderr b/src/test/ui/native-library-link-flags/empty-kind-2.stderr index 37846c0b06f69..3e5b054933999 100644 --- a/src/test/ui/native-library-link-flags/empty-kind-2.stderr +++ b/src/test/ui/native-library-link-flags/empty-kind-2.stderr @@ -1,2 +1,2 @@ -error: unknown library kind ``, expected one of: static, dylib, framework +error: unknown library kind ``, expected one of: static, dylib, framework, link-arg diff --git a/src/test/ui/native-library-link-flags/link-arg-error.rs b/src/test/ui/native-library-link-flags/link-arg-error.rs new file mode 100644 index 0000000000000..e041650d024f4 --- /dev/null +++ b/src/test/ui/native-library-link-flags/link-arg-error.rs @@ -0,0 +1,4 @@ +// compile-flags: -l link-arg:+bundle=arg -Z unstable-options +// error-pattern: linking modifier `bundle` is only compatible with `static` linking kind + +fn main() {} diff --git a/src/test/ui/native-library-link-flags/link-arg-error.stderr b/src/test/ui/native-library-link-flags/link-arg-error.stderr new file mode 100644 index 0000000000000..e1d01e1415274 --- /dev/null +++ b/src/test/ui/native-library-link-flags/link-arg-error.stderr @@ -0,0 +1,2 @@ +error: linking modifier `bundle` is only compatible with `static` linking kind + diff --git a/src/test/ui/native-library-link-flags/link-arg-from-rs.rs b/src/test/ui/native-library-link-flags/link-arg-from-rs.rs new file mode 100644 index 0000000000000..075e4d9e79e46 --- /dev/null +++ b/src/test/ui/native-library-link-flags/link-arg-from-rs.rs @@ -0,0 +1,8 @@ +// link-arg is not supposed to be usable in #[link] attributes + +// compile-flags: +// error-pattern: error[E0458]: unknown link kind `link-arg`, expected one of: static, dylib, framework, raw-dylib + +#[link(kind = "link-arg")] +extern "C" {} +pub fn main() {} diff --git a/src/test/ui/native-library-link-flags/link-arg-from-rs.stderr b/src/test/ui/native-library-link-flags/link-arg-from-rs.stderr new file mode 100644 index 0000000000000..69a7825c0b105 --- /dev/null +++ b/src/test/ui/native-library-link-flags/link-arg-from-rs.stderr @@ -0,0 +1,16 @@ +error[E0458]: unknown link kind `link-arg`, expected one of: static, dylib, framework, raw-dylib + --> $DIR/link-arg-from-rs.rs:6:15 + | +LL | #[link(kind = "link-arg")] + | ^^^^^^^^^^ unknown link kind + +error[E0459]: `#[link]` attribute requires a `name = "string"` argument + --> $DIR/link-arg-from-rs.rs:6:1 + | +LL | #[link(kind = "link-arg")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `name` argument + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0458, E0459. +For more information about an error, try `rustc --explain E0458`. diff --git a/src/tools/clippy/tests/ui/crashes/ice-6252.stderr b/src/tools/clippy/tests/ui/crashes/ice-6252.stderr index a1e37e7317b2e..638e4a5484932 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-6252.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-6252.stderr @@ -30,15 +30,7 @@ LL | const VAL: T; LL | impl TypeVal for Multiply where N: TypeVal {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation -error: constant expression depends on a generic parameter - --> $DIR/ice-6252.rs:13:9 - | -LL | [1; >::VAL]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: this may fail depending on what value the parameter takes - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0046, E0412. For more information about an error, try `rustc --explain E0046`.