BareFunctionDecl { unsafety: bare_fn.unsafety, abi: bare_fn.abi, decl, generic_params } } <del> /// This visitor is used to go through only the "top level" of a item and not enter any sub /// item while looking for a given `Ident` which is stored into `item` if found. struct OneLevelVisitor<'hir> { </del> <ins> /// Get DefId of of an item's user-visible parent. /// /// "User-visible" should account for re-exporting and inlining, which is why this function isn't /// just `tcx.parent(def_id)`. If the provided `path` has more than one path element, the `DefId` /// of the second-to-last will be given. /// /// ```text /// use crate::foo::Bar; ///            ^^^ DefId of this item will be returned /// ``` /// /// If the provided path has only one item, `tcx.parent(def_id)` will be returned instead. fn get_path_parent_def_id( tcx: TyCtxt<'_>, def_id: DefId, path: &hir::UsePath<'_>, ) -> Option<DefId> { if let [.., parent_segment, _] = &path.segments { match parent_segment.res { hir::def::Res::Def(_, parent_def_id) => Some(parent_def_id), _ if parent_segment.ident.name == kw::Crate => { // In case the "parent" is the crate, it'll give `Res::Err` so we need to // circumvent it this way. Some(tcx.parent(def_id)) } _ => None, } } else { // If the path doesn't have a parent, then the parent is the current module. Some(tcx.parent(def_id)) } } /// This visitor is used to find an HIR Item based on its `use` path. This doesn't use the ordinary /// name resolver because it does not walk all the way through a chain of re-exports. pub(crate) struct OneLevelVisitor<'hir> { </ins> map: rustc_middle::hir::map::Map<'hir>, <del> item: Option<&'hir hir::Item<'hir>>, </del> <ins> pub(crate) item: Option<&'hir hir::Item<'hir>>, </ins> looking_for: Ident, target_def_id: LocalDefId, } impl<'hir> OneLevelVisitor<'hir> { <del> fn new(map: rustc_middle::hir::map::Map<'hir>, target_def_id: LocalDefId) -> Self { </del> <ins> pub(crate) fn new(map: rustc_middle::hir::map::Map<'hir>, target_def_id: LocalDefId) -> Self { </ins> Self { map, item: None, looking_for: Ident::empty(), target_def_id } } <del> fn reset(&mut self, looking_for: Ident) { self.looking_for = looking_for; </del> <ins> pub(crate) fn find_target( &mut self, tcx: TyCtxt<'_>, def_id: DefId, path: &hir::UsePath<'_>, ) -> Option<&'hir hir::Item<'hir>> { let parent_def_id = get_path_parent_def_id(tcx, def_id, path)?; let parent = self.map.get_if_local(parent_def_id)?; // We get the `Ident` we will be looking for into `item`. self.looking_for = path.segments[path.segments.len() - 1].ident; // We reset the `item`. </ins> self.item = None; <ins> match parent { hir::Node::Item(parent_item) => { hir::intravisit::walk_item(self, parent_item); } hir::Node::Crate(m) => { hir::intravisit::walk_mod( self, m, tcx.local_def_id_to_hir_id(parent_def_id.as_local().unwrap()), ); } _ => return None, } self.item </ins> } }


add_without_unwanted_attributes(attributes, hir_map.attrs(item.hir_id()), is_inline); } <del> let def_id = if let [.., parent_segment, _] = &path.segments { match parent_segment.res { hir::def::Res::Def(_, def_id) => def_id, _ if parent_segment.ident.name == kw::Crate => { // In case the "parent" is the crate, it'll give `Res::Err` so we need to // circumvent it this way. tcx.parent(item.owner_id.def_id.to_def_id()) } _ => break, } } else { // If the path doesn't have a parent, then the parent is the current module. tcx.parent(item.owner_id.def_id.to_def_id()) }; let Some(parent) = hir_map.get_if_local(def_id) else { break }; // We get the `Ident` we will be looking for into `item`. let looking_for = path.segments[path.segments.len() - 1].ident; visitor.reset(looking_for); match parent { hir::Node::Item(parent_item) => { hir::intravisit::walk_item(&mut visitor, parent_item); } hir::Node::Crate(m) => { hir::intravisit::walk_mod( &mut visitor, m, tcx.local_def_id_to_hir_id(def_id.as_local().unwrap()), ); } _ => break, } if let Some(i) = visitor.item { </del> <ins> if let Some(i) = visitor.find_target(tcx, item.owner_id.def_id.to_def_id(), path) { </ins> item = i; } else { break;


use std::mem; <del> use crate::clean::{cfg::Cfg, AttributesExt, NestedAttributesExt}; </del> <ins> use crate::clean::{cfg::Cfg, AttributesExt, NestedAttributesExt, OneLevelVisitor}; </ins> use crate::core; /// This module is used to store stuff from Rust's AST in a more convenient


renamed: Option<Symbol>, glob: bool, please_inline: bool, <ins> path: &hir::UsePath<'_>, </ins> ) -> bool { debug!("maybe_inline_local res: {:?}", res);


return false; } <ins> if !please_inline && let mut visitor = OneLevelVisitor::new(self.cx.tcx.hir(), res_did) && let Some(item) = visitor.find_target(self.cx.tcx, def_id.to_def_id(), path) && let item_def_id = item.owner_id.def_id && item_def_id != def_id && self .cx .cache .effective_visibilities .is_directly_public(self.cx.tcx, item_def_id.to_def_id()) && !inherits_doc_hidden(self.cx.tcx, item_def_id) { // The imported item is public and not `doc(hidden)` so no need to inline it. return false; } </ins> let ret = match tcx.hir().get_by_def_id(res_did) { Node::Item(&hir::Item { kind: hir::ItemKind::Mod(ref m), .. }) if glob => { let prev = mem::replace(&mut self.inlining, true);


ident, is_glob, please_inline, <ins> path, </ins> ) { continue; }


<ins> // This test ensures that the `struct.B.html` only exists in `a`: // since `a::B` is public (and inlined too), `self::a::B` doesn't // need to be inlined as well. #![crate_name = "foo"] pub mod a { // @has 'foo/a/index.html' // Should only contain "Structs". // @count - '//*[@id="main-content"]//*[@class="item-table"]' 1 // @has - '//*[@id="structs"]' 'Structs' // @has - '//*[@id="main-content"]//a[@href="struct.A.html"]' 'A' // @has - '//*[@id="main-content"]//a[@href="struct.B.html"]' 'B' mod b { pub struct B; } pub use self::b::B; pub struct A; } // @has 'foo/index.html' // @!has - '//*[@id="structs"]' 'Structs' // @has - '//*[@id="reexports"]' 'Re-exports' // @has - '//*[@id="modules"]' 'Modules' // @has - '//*[@id="main-content"]//*[@id="reexport.A"]' 'pub use self::a::A;' // @has - '//*[@id="main-content"]//*[@id="reexport.B"]' 'pub use self::a::B;' // Should only contain "Modules" and "Re-exports". // @count - '//*[@id="main-content"]//*[@class="item-table"]' 2 pub use self::a::{A, B}; </ins>


None } <ins> fn suggest_missing_writer( &self, rcvr_ty: Ty<'tcx>, args: (&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>]), ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { let (ty_str, _ty_file) = self.tcx.short_ty_string(rcvr_ty); let mut err = struct_span_err!(self.tcx.sess, args.0.span, E0599, "cannot write into `{}`", ty_str); err.span_note( args.0.span, "must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method", ); if let ExprKind::Lit(_) = args.0.kind { err.span_help( args.0.span.shrink_to_lo(), "a writer is needed before this format string", ); }; err } </ins> pub fn report_no_match_method_error( &self, mut span: Span,


} } <del> let mut err = struct_span_err!( tcx.sess, span, E0599, "no {} named `{}` found for {} `{}` in the current scope", item_kind, item_name, rcvr_ty.prefix_string(self.tcx), ty_str_reported, ); </del> <ins> let is_write = sugg_span.ctxt().outer_expn_data().macro_def_id.map_or(false, |def_id| { tcx.is_diagnostic_item(sym::write_macro, def_id) || tcx.is_diagnostic_item(sym::writeln_macro, def_id) }) && item_name.name == Symbol::intern("write_fmt"); let mut err = if is_write && let Some(args) = args { self.suggest_missing_writer(rcvr_ty, args) } else { struct_span_err!( tcx.sess, span, E0599, "no {} named `{}` found for {} `{}` in the current scope", item_kind, item_name, rcvr_ty.prefix_string(self.tcx), ty_str_reported, ) }; </ins> if tcx.sess.source_map().is_multiline(sugg_span) { err.span_label(sugg_span.with_hi(span.lo()), ""); }


<ins> // Check error for missing writer in writeln! and write! macro fn main() { let x = 1; let y = 2; write!("{}_{}", x, y); //~^ ERROR format argument must be a string literal //~| HELP you might be missing a string literal to format with //~| ERROR cannot write into `&'static str` //~| NOTE must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method //~| HELP a writer is needed before this format string writeln!("{}_{}", x, y); //~^ ERROR format argument must be a string literal //~| HELP you might be missing a string literal to format with //~| ERROR cannot write into `&'static str` //~| NOTE must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method //~| HELP a writer is needed before this format string } </ins>


<ins> error: format argument must be a string literal --> $DIR/missing-writer.rs:5:21 | LL |     write!("{}_{}", x, y); |                     ^ | help: you might be missing a string literal to format with | LL |     write!("{}_{}", "{} {}", x, y); |                     ++++++++ error: format argument must be a string literal --> $DIR/missing-writer.rs:11:23 | LL |     writeln!("{}_{}", x, y); |                       ^ | help: you might be missing a string literal to format with | LL |     writeln!("{}_{}", "{} {}", x, y); |                       ++++++++ error[E0599]: cannot write into `&'static str` --> $DIR/missing-writer.rs:5:12 | LL |     write!("{}_{}", x, y); |     -------^^^^^^^------- method not found in `&str` | note: must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method --> $DIR/missing-writer.rs:5:12 | LL |     write!("{}_{}", x, y); |            ^^^^^^^ help: a writer is needed before this format string --> $DIR/missing-writer.rs:5:12 | LL |     write!("{}_{}", x, y); |            ^ error[E0599]: cannot write into `&'static str` --> $DIR/missing-writer.rs:11:14 | LL |     writeln!("{}_{}", x, y); |     ---------^^^^^^^------- method not found in `&str` | note: must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method --> $DIR/missing-writer.rs:11:14 | LL |     writeln!("{}_{}", x, y); |              ^^^^^^^ help: a writer is needed before this format string --> $DIR/missing-writer.rs:11:14 | LL |     writeln!("{}_{}", x, y); |              ^ error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0599`. </ins>


--> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL error[E0599]: the method `write_fmt` exists for struct `BufWriter<&dyn Write>`, but its trait bounds were not satisfied <del> --> $DIR/mut-borrow-needed-by-trait.rs:21:5 </del> <ins> --> $DIR/mut-borrow-needed-by-trait.rs:21:14 </ins> | LL |     writeln!(fp, "hello world").unwrap(); <del> |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ method cannot be called on `BufWriter<&dyn Write>` due to unsatisfied trait bounds </del> <ins> |     ---------^^---------------- method cannot be called on `BufWriter<&dyn Write>` due to unsatisfied trait bounds </ins> --> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL | = note: doesn't satisfy `BufWriter<&dyn std::io::Write>: std::io::Write` | <ins> note: must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method --> $DIR/mut-borrow-needed-by-trait.rs:21:14 | LL |     writeln!(fp, "hello world").unwrap(); |              ^^ </ins> = note: the following trait bounds were not satisfied: `&dyn std::io::Write: std::io::Write` which is required by `BufWriter<&dyn std::io::Write>: std::io::Write` <del> = note: this error originates in the macro `writeln` (in Nightly builds, run with -Z macro-backtrace for more info) </del> error: aborting due to 3 previous errors


r: ty::Region<'tcx>, ) -> ty::Region<'tcx> { match *r { <del> ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReErased | ty::ReStatic => r, </del> <ins> ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReErased | ty::ReStatic | ty::ReError(_) => r, </ins> ty::ReVar(_) => canonicalizer.canonical_var_for_region_in_root_universe(r), <del> _ => { </del> <ins> ty::RePlaceholder(..) | ty::ReLateBound(..) => { </ins> // We only expect region names that the user can type. bug!("unexpected region in query response: `{:?}`", r) }


<ins> // Regression test for #109072. // Check that we don't ICE when canonicalizing user annotation. trait Lt<'a> { type T; } impl Lt<'missing> for () { //~ ERROR undeclared lifetime type T = &'missing (); //~ ERROR undeclared lifetime } fn main() { let _: <() as Lt<'_>>::T = &(); } </ins>


<ins> error[E0261]: use of undeclared lifetime name `'missing` --> $DIR/region-error-ice-109072.rs:8:9 | LL | impl Lt<'missing> for () { |     -   ^^^^^^^^ undeclared lifetime |     | |     help: consider introducing lifetime `'missing` here: `<'missing>` error[E0261]: use of undeclared lifetime name `'missing` --> $DIR/region-error-ice-109072.rs:9:15 | LL |     type T = &'missing (); |               ^^^^^^^^ undeclared lifetime | help: consider introducing lifetime `'missing` here | LL |     type T<'missing> = &'missing (); |           ++++++++++ help: consider introducing lifetime `'missing` here | LL | impl<'missing> Lt<'missing> for () { |     ++++++++++ error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0261`. </ins>


e.note( "the macro call doesn't expand to an expression, but it can expand to a statement", ); <del> e.span_suggestion_verbose( site_span.shrink_to_hi(), "add `;` to interpret the expansion as a statement", ";", Applicability::MaybeIncorrect, ); </del> <ins> if parser.token == token::Semi { if let Ok(snippet) = parser.sess.source_map().span_to_snippet(site_span) { e.span_suggestion_verbose( site_span, "surround the macro invocation with `{}` to interpret the expansion as a statement", format!("{{ {}; }}", snippet), Applicability::MaybeIncorrect, ); } } else { e.span_suggestion_verbose( site_span.shrink_to_hi(), "add `;` to interpret the expansion as a statement", ";", Applicability::MaybeIncorrect, ); } </ins> } }, _ => annotate_err_with_kind(&mut e, kind, site_span),


<ins> macro_rules! statement { () => {;}; //~ ERROR expected expression } fn main() { let _ = statement!(); } </ins>


<ins> error: expected expression, found `;` --> $DIR/issue-109237.rs:2:12 | LL |     () => {;}; |            ^ expected expression ... LL |     let _ = statement!(); |             ------------ in this macro invocation | = note: the macro call doesn't expand to an expression, but it can expand to a statement = note: this error originates in the macro `statement` (in Nightly builds, run with -Z macro-backtrace for more info) help: surround the macro invocation with `{}` to interpret the expansion as a statement | LL |     let _ = { statement!(); }; |             ~~~~~~~~~~~~~~~~~ error: aborting due to previous error </ins>


// the expected const's type. Specifically, we don't want const infer vars // to do any type shapeshifting before and after resolution. if let Err(guar) = compatible_types { <del> return Ok(self.tcx.const_error_with_guaranteed( if relation.a_is_expected() { a.ty() } else { b.ty() }, guar, )); </del> <ins> // HACK: equating both sides with `[const error]` eagerly prevents us // from leaving unconstrained inference vars during things like impl // matching in the solver. let a_error = self.tcx.const_error_with_guaranteed(a.ty(), guar); if let ty::ConstKind::Infer(InferConst::Var(vid)) = a.kind() { return self.unify_const_variable(vid, a_error); } let b_error = self.tcx.const_error_with_guaranteed(b.ty(), guar); if let ty::ConstKind::Infer(InferConst::Var(vid)) = b.kind() { return self.unify_const_variable(vid, b_error); } return Ok(if relation.a_is_expected() { a_error } else { b_error }); </ins> } match (a.kind(), b.kind()) {


use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{error_code, DelayDm, Diagnostic}; use rustc_hir::def_id::{DefId, LocalDefId}; <del> use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt}; </del> <ins> use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt}; </ins> use rustc_middle::ty::{InternalSubsts, SubstsRef}; use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK; use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS;


impl_span: Span, err: &mut Diagnostic, ) { <ins> if (overlap.trait_ref, overlap.self_ty).references_error() { err.downgrade_to_delayed_bug(); } </ins> match tcx.span_of_impl(overlap.with_impl) { Ok(span) => { err.span_label(span, "first implementation here");


<ins> // incremental #![crate_type = "lib"] trait Q { const ASSOC: usize; } impl<const N: u64> Q for [u8; N] { //~^ ERROR mismatched types const ASSOC: usize = 1; } pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] { todo!() } </ins>


<ins> error[E0308]: mismatched types --> $DIR/bad-subst-const-kind.rs:8:31 | LL | impl<const N: u64> Q for [u8; N] { |                               ^ expected `usize`, found `u64` error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. </ins>


// An impl that has an erroneous const substitution should not specialize one // that is well-formed. <ins> #[derive(Clone)] </ins> struct S<const L: usize>; impl<const N: i32> Copy for S<N> {} <ins> //~^ ERROR the constant `N` is not of type `usize` </ins> impl<const M: usize> Copy for S<M> {} <del> //~^ ERROR conflicting implementations of trait `Copy` for type `S<_>` </del> fn main() {}


<del> error[E0119]: conflicting implementations of trait `Copy` for type `S<_>` --> $DIR/bad-const-wf-doesnt-specialize.rs:9:1 </del> <ins> error: the constant `N` is not of type `usize` --> $DIR/bad-const-wf-doesnt-specialize.rs:8:29 </ins> | LL | impl<const N: i32> Copy for S<N> {} <del> | -------------------------------- first implementation here LL | impl<const M: usize> Copy for S<M> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `S<_>` </del> <ins> |                             ^^^^ | note: required by a bound in `S` --> $DIR/bad-const-wf-doesnt-specialize.rs:6:10 | LL | struct S<const L: usize>; |          ^^^^^^^^^^^^^^ required by this bound in `S` </ins> error: aborting due to previous error <del> For more information about this error, try `rustc --explain E0119`. </del>


use rustc_infer::traits::ObligationCause; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; use rustc_middle::middle::stability::AllowUnstable; <ins> use rustc_middle::ty::fold::FnMutDelegate; </ins> use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef}; use rustc_middle::ty::DynKind; use rustc_middle::ty::GenericParamDefKind;


let param_env = tcx.param_env(block.owner.to_def_id()); let cause = ObligationCause::misc(span, block.owner.def_id); let mut fulfillment_errors = Vec::new(); <del> let mut applicable_candidates: Vec<_> = candidates .iter() .filter_map(|&(impl_, (assoc_item, def_scope))| { infcx.probe(|_| { let ocx = ObligationCtxt::new_in_snapshot(&infcx); </del> <ins> let mut applicable_candidates: Vec<_> = infcx.probe(|_| { let universe = infcx.create_next_universe(); // Regions are not considered during selection. let self_ty = tcx.replace_escaping_bound_vars_uncached( self_ty, FnMutDelegate { regions: &mut |_| tcx.lifetimes.re_erased, types: &mut |bv| { tcx.mk_placeholder(ty::PlaceholderType { universe, name: bv.kind }) }, consts: &mut |bv, ty| { tcx.mk_const(ty::PlaceholderConst { universe, name: bv }, ty) }, }, ); </ins> <del> let impl_ty = tcx.type_of(impl_); let impl_substs = infcx.fresh_item_substs(impl_); let impl_ty = impl_ty.subst(tcx, impl_substs); let impl_ty = ocx.normalize(&cause, param_env, impl_ty); </del> <ins> candidates .iter() .filter_map(|&(impl_, (assoc_item, def_scope))| { infcx.probe(|_| { let ocx = ObligationCtxt::new_in_snapshot(&infcx); </ins> <del> // Check that the Self-types can be related. // FIXME(fmease): Should we use `eq` here? ocx.sup(&ObligationCause::dummy(), param_env, impl_ty, self_ty).ok()?; </del> <ins> let impl_ty = tcx.type_of(impl_); let impl_substs = infcx.fresh_item_substs(impl_); let impl_ty = impl_ty.subst(tcx, impl_substs); let impl_ty = ocx.normalize(&cause, param_env, impl_ty); </ins> <del> // Check whether the impl imposes obligations we have to worry about. let impl_bounds = tcx.predicates_of(impl_); let impl_bounds = impl_bounds.instantiate(tcx, impl_substs); </del> <ins> // Check that the Self-types can be related. // FIXME(fmease): Should we use `eq` here? ocx.sup(&ObligationCause::dummy(), param_env, impl_ty, self_ty).ok()?; </ins> <del> let impl_bounds = ocx.normalize(&cause, param_env, impl_bounds); </del> <ins> // Check whether the impl imposes obligations we have to worry about. let impl_bounds = tcx.predicates_of(impl_); let impl_bounds = impl_bounds.instantiate(tcx, impl_substs); </ins> <del> let impl_obligations = traits::predicates_for_generics( |_, _| cause.clone(), param_env, impl_bounds, ); </del> <ins> let impl_bounds = ocx.normalize(&cause, param_env, impl_bounds); </ins> <del> ocx.register_obligations(impl_obligations); </del> <ins> let impl_obligations = traits::predicates_for_generics( |_, _| cause.clone(), param_env, impl_bounds, ); </ins> <del> let mut errors = ocx.select_where_possible(); if !errors.is_empty() { fulfillment_errors.append(&mut errors); return None; } </del> <ins> ocx.register_obligations(impl_obligations); let mut errors = ocx.select_where_possible(); if !errors.is_empty() { fulfillment_errors.append(&mut errors); return None; } </ins> <del> // FIXME(fmease): Unsolved vars can escape this InferCtxt snapshot. Some((assoc_item, def_scope, infcx.resolve_vars_if_possible(impl_substs))) </del> <ins> // FIXME(fmease): Unsolved vars can escape this InferCtxt snapshot. Some((assoc_item, def_scope, infcx.resolve_vars_if_possible(impl_substs))) }) </ins> }) <del> }) .collect(); </del> <ins> .collect() }); </ins> if applicable_candidates.len() > 1 { return Err(self.complain_about_ambiguous_inherent_assoc_type(


<ins> #![feature(inherent_associated_types, non_lifetime_binders, type_alias_impl_trait)] #![allow(incomplete_features)] struct Lexer<T>(T); impl Lexer<i32> { type Cursor = (); } type X = impl for<T> Fn() -> Lexer<T>::Cursor; //~ ERROR associated type `Cursor` not found for `Lexer<T>` in the current scope fn main() {} </ins>


<ins> error[E0220]: associated type `Cursor` not found for `Lexer<T>` in the current scope --> $DIR/issue-109299-1.rs:10:40 | LL | struct Lexer<T>(T); | --------------- associated item `Cursor` not found for this struct ... LL | type X = impl for<T> Fn() -> Lexer<T>::Cursor; |                                        ^^^^^^ associated item not found in `Lexer<T>` | = note: the associated type was found for - `Lexer<i32>` error: aborting due to previous error For more information about this error, try `rustc --explain E0220`. </ins>


<ins> #![feature(inherent_associated_types)] #![allow(incomplete_features)] struct Lexer<'d>(&'d ()); impl Lexer<'d> { //~ ERROR use of undeclared lifetime name `'d` type Cursor = (); } fn test(_: Lexer::Cursor) {} fn main() {} </ins>


<ins> error[E0261]: use of undeclared lifetime name `'d` --> $DIR/issue-109299.rs:6:12 | LL | impl Lexer<'d> { |     -      ^^ undeclared lifetime |     | |     help: consider introducing lifetime `'d` here: `<'d>` error: aborting due to previous error For more information about this error, try `rustc --explain E0261`. </ins>


//        the ugliness comes from inlining across crates where //        everything comes in as a fully resolved QPath (hard to //        look at).  match href(trait_.def_id(), cx) { Ok((ref url, _, ref path)) if !f.alternate() => { write!( f, "{name}{args}", url = url, shortty = ItemType::AssocType, name = assoc.name, path = join_with_double_colon(path), args = assoc.args.print(cx), )?; } _ => write!(f, "{}{:#}", assoc.name, assoc.args.print(cx))?, } Ok(())   if !f.alternate() && let Ok((url, _, path)) = href(trait_.def_id(), cx) { write!( f, "{name}", shortty = ItemType::AssocType, name = assoc.name, path = join_with_double_colon(&path), ) } else { write!(f, "{}", assoc.name) }?; // Carry `f.alternate()` into this display w/o branching manually. fmt::Display::fmt(&assoc.args.print(cx), f)  } } }


<ins> // Make sure that we escape the arguments of the GAT projection even if we fail to compute // the href of the corresponding trait (in this case it is private). // Further, test that we also linkify the GAT arguments. // @has 'issue_109488/type.A.html' // @has - '//pre[@class="rust item-decl"]' '<S as Tr>::P<Option<i32>>' // @has - '//pre[@class="rust item-decl"]//a[@class="enum"]/@href' '{{channel}}/core/option/enum.Option.html' pub type A = <S as Tr>::P<Option<i32>>; /*private*/ trait Tr { type P<T>; } pub struct S; impl Tr for S { type P<T> = (); } </ins>


use crate::builder::crate_description; use crate::builder::Cargo; <del> use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step}; </del> <ins> use crate::builder::{Builder, Kind, PathSet, RunConfig, ShouldRun, Step, TaskPath}; </ins> use crate::cache::{Interned, INTERNER}; use crate::config::{LlvmLibunwind, RustcLto, TargetSelection}; use crate::dist;


pub backend: Interned<String>, } <ins> fn needs_codegen_config(run: &RunConfig<'_>) -> bool { let mut needs_codegen_cfg = false; for path_set in &run.paths { needs_codegen_cfg = match path_set { PathSet::Set(set) => set.iter().any(|p| is_codegen_cfg_needed(p, run)), PathSet::Suite(suite) => is_codegen_cfg_needed(&suite, run), } } needs_codegen_cfg } const CODEGEN_BACKEND_PREFIX: &str = "rustc_codegen_"; fn is_codegen_cfg_needed(path: &TaskPath, run: &RunConfig<'_>) -> bool { if path.path.to_str().unwrap().contains(&CODEGEN_BACKEND_PREFIX) { let mut needs_codegen_backend_config = true; for &backend in &run.builder.config.rust_codegen_backends { if path .path .to_str() .unwrap() .ends_with(&(CODEGEN_BACKEND_PREFIX.to_owned() + &backend)) { needs_codegen_backend_config = false; } } if needs_codegen_backend_config { run.builder.info( "Warning: no codegen-backends config matched the requested path to build a codegen backend.  Help: add backend to codegen-backends in config.toml.", ); return true; } } return false; } </ins> impl Step for CodegenBackend { type Output = (); const ONLY_HOSTS: bool = true;


} fn make_run(run: RunConfig<'_>) { <ins> if needs_codegen_config(&run) { return; } </ins> for &backend in &run.builder.config.rust_codegen_backends { if backend == "llvm" { continue; // Already built as part of rustc


let tcx = self.tcx; let def_id = instance.def_id(); <del> let containing_scope = get_containing_scope(self, instance); </del> <ins> let (containing_scope, is_method) = get_containing_scope(self, instance); </ins> let span = tcx.def_span(def_id); let loc = self.lookup_debug_loc(span.lo()); let file_metadata = file_metadata(self, &loc.file);


} } <del> unsafe { return llvm::LLVMRustDIBuilderCreateFunction( </del> <ins> // When we're adding a method to a type DIE, we only want a DW_AT_declaration there, because // LLVM LTO can't unify type definitions when a child DIE is a full subprogram definition. // When we use this `decl` below, the subprogram definition gets created at the CU level // with a DW_AT_specification pointing back to the type's declaration. let decl = is_method.then(|| unsafe { llvm::LLVMRustDIBuilderCreateMethod( DIB(self), containing_scope, name.as_ptr().cast(), name.len(), linkage_name.as_ptr().cast(), linkage_name.len(), file_metadata, loc.line, function_type_metadata, flags, spflags & !DISPFlags::SPFlagDefinition, template_parameters, ) }); return unsafe { llvm::LLVMRustDIBuilderCreateFunction( </ins> DIB(self), containing_scope, name.as_ptr().cast(),


spflags, maybe_definition_llfn, template_parameters, <del> None, ); } </del> <ins> decl, ) }; </ins> fn get_function_signature<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>,


names } <ins> /// Returns a scope, plus `true` if that's a type scope for "class" methods, /// otherwise `false` for plain namespace scopes. </ins> fn get_containing_scope<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>, <del> ) -> &'ll DIScope { </del> <ins> ) -> (&'ll DIScope, bool) { </ins> // First, let's see if this is a method within an inherent impl. Because // if yes, we want to make the result subroutine DIE a child of the // subroutine's self-type. <del> let self_type = cx.tcx.impl_of_method(instance.def_id()).and_then(|impl_def_id| { </del> <ins> if let Some(impl_def_id) = cx.tcx.impl_of_method(instance.def_id()) { </ins> // If the method does *not* belong to a trait, proceed if cx.tcx.trait_id_of_impl(impl_def_id).is_none() { let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions(


// Only "class" methods are generally understood by LLVM, // so avoid methods on other types (e.g., `<*mut T>::null`). <del> match impl_self_ty.kind() { ty::Adt(def, ..) if !def.is_box() => { // Again, only create type information if full debuginfo is enabled if cx.sess().opts.debuginfo == DebugInfo::Full && !impl_self_ty.has_param() { Some(type_di_node(cx, impl_self_ty)) } else { Some(namespace::item_namespace(cx, def.did())) } </del> <ins> if let ty::Adt(def, ..) = impl_self_ty.kind() && !def.is_box() { // Again, only create type information if full debuginfo is enabled if cx.sess().opts.debuginfo == DebugInfo::Full && !impl_self_ty.has_param() { return (type_di_node(cx, impl_self_ty), true); } else { return (namespace::item_namespace(cx, def.did()), false); </ins> } <del> _ => None, </del> } } else { // For trait method impls we still use the "parallel namespace" // strategy <del> None </del> } <del> }); </del> <ins> } </ins> <del> self_type.unwrap_or_else(|| { namespace::item_namespace( cx, DefId { krate: instance.def_id().krate, index: cx .tcx .def_key(instance.def_id()) .parent .expect("get_containing_scope: missing parent?"), }, ) }) </del> <ins> let scope = namespace::item_namespace( cx, DefId { krate: instance.def_id().krate, index: cx .tcx .def_key(instance.def_id()) .parent .expect("get_containing_scope: missing parent?"), }, ); (scope, false) </ins> } }


Decl: Option<&'a DIDescriptor>, ) -> &'a DISubprogram; <ins> pub fn LLVMRustDIBuilderCreateMethod<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIDescriptor, Name: *const c_char, NameLen: size_t, LinkageName: *const c_char, LinkageNameLen: size_t, File: &'a DIFile, LineNo: c_uint, Ty: &'a DIType, Flags: DIFlags, SPFlags: DISPFlags, TParam: &'a DIArray, ) -> &'a DISubprogram; </ins> pub fn LLVMRustDIBuilderCreateBasicType<'a>( Builder: &DIBuilder<'a>, Name: *const c_char,


return wrap(Sub); } <ins> extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMethod( LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, const char *LinkageName, size_t LinkageNameLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, LLVMRustDIFlags Flags, LLVMRustDISPFlags SPFlags, LLVMMetadataRef TParam) { DITemplateParameterArray TParams = DITemplateParameterArray(unwrap<MDTuple>(TParam)); DISubprogram::DISPFlags llvmSPFlags = fromRust(SPFlags); DINode::DIFlags llvmFlags = fromRust(Flags); DISubprogram *Sub = Builder->createMethod( unwrapDI<DIScope>(Scope), StringRef(Name, NameLen), StringRef(LinkageName, LinkageNameLen), unwrapDI<DIFile>(File), LineNo, unwrapDI<DISubroutineType>(Ty), 0, 0, nullptr, // VTable params aren't used llvmFlags, llvmSPFlags, TParams); return wrap(Sub); } </ins> extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateBasicType( LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen, uint64_t SizeInBits, unsigned Encoding) {


<ins> # ignore-cross-compile include ../tools.mk # With the upgrade to LLVM 16, this was getting: # #   error: Cannot represent a difference across sections # # The error stemmed from DI function definitions under type scopes, fixed by # only declaring in type scope and defining the subprogram elsewhere. all: $(RUSTC) lib.rs --test -C lto=fat -C debuginfo=2 -C incremental=$(TMPDIR)/inc-fat </ins>


<ins> extern crate alloc; #[cfg(test)] mod tests { #[test] fn something_alloc() { assert_eq!(Vec::<u32>::new(), Vec::<u32>::new()); } } </ins>


sugar for dynamic allocations via `malloc` and `free`: ```rust,ignore (libc-is-finicky) <del> #![feature(lang_items, box_syntax, start, libc, core_intrinsics, rustc_private)] </del> <ins> #![feature(lang_items, start, libc, core_intrinsics, rustc_private, rustc_attrs)] </ins> #![no_std] use core::intrinsics; use core::panic::PanicInfo; <ins> use core::ptr::NonNull; </ins> extern crate libc; <del> struct Unique<T>(*mut T); </del> <ins> struct Unique<T>(NonNull<T>); </ins> #[lang = "owned_box"] pub struct Box<T>(Unique<T>); <ins> impl<T> Box<T> { pub fn new(x: T) -> Self { #[rustc_box] Box::new(x) } } </ins> #[lang = "exchange_malloc"] unsafe fn allocate(size: usize, _align: usize) -> *mut u8 { let p = libc::malloc(size as libc::size_t) as *mut u8;


#[start] fn main(_argc: isize, _argv: *const *const u8) -> isize { <del> let _x = box 1; </del> <ins> let _x = Box::new(1); </ins> 0 } #[lang = "eh_personality"] extern fn rust_eh_personality() {} <del> #[lang = "panic_impl"] extern fn rust_begin_panic(info: &PanicInfo) -> ! { unsafe { intrinsics::abort() } } </del> <ins> #[lang = "panic_impl"] extern fn rust_begin_panic(_info: &PanicInfo) -> ! { intrinsics::abort() } </ins> #[no_mangle] pub extern fn rust_eh_register_frames () {} #[no_mangle] pub extern fn rust_eh_unregister_frames () {} ```


that warns about any item named `lintme`. ```rust,ignore (requires-stage-2) <del> #![feature(box_syntax, rustc_private)] </del> <ins> #![feature(rustc_private)] </ins> extern crate rustc_ast;


#[no_mangle] fn __rustc_plugin_registrar(reg: &mut Registry) { reg.lint_store.register_lints(&[&TEST_LINT]); <del> reg.lint_store.register_early_pass(|| box Pass); </del> <ins> reg.lint_store.register_early_pass(|| Box::new(Pass)); </ins> } ```


let mut head = self.head.index.load(Ordering::Acquire); let mut block = self.head.block.load(Ordering::Acquire); <ins> // If we're going to be dropping messages we need to synchronize with initialization if head >> SHIFT != tail >> SHIFT { // The block can be null here only if a sender is in the process of initializing the // channel while another sender managed to send a message by inserting it into the // semi-initialized channel and advanced the tail. // In that case, just wait until it gets initialized. while block.is_null() { backoff.spin_heavy(); block = self.head.block.load(Ordering::Acquire); } } </ins> unsafe { // Drop all messages between head and tail and deallocate the heap-allocated blocks. while head >> SHIFT != tail >> SHIFT {


// Forward test filters. cargo.arg("--").args(builder.config.cmd.test_args()); <del> add_flags_and_try_run_tests(builder, &mut cargo.into()); </del> <ins> // This can NOT be `add_flags_and_try_run_tests` since the Miri test runner // does not understand those flags! let mut cargo = Command::from(cargo); builder.run(&mut cargo); </ins> // # Run `cargo miri test`. // This is just a smoke test (Miri's own CI invokes this in a bunch of different ways and ensures


}; use crate::traits::{Obligation, PredicateObligations}; <del> use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; </del> <ins> use rustc_middle::ty::relate::{ relate_args_invariantly, relate_args_with_variances, Relate, RelateResult, TypeRelation, }; </ins> use rustc_middle::ty::TyVar; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span;


self.fields.infcx.tcx } <ins> fn relate_item_args( &mut self, item_def_id: rustc_hir::def_id::DefId, a_arg: ty::GenericArgsRef<'tcx>, b_arg: ty::GenericArgsRef<'tcx>, ) -> RelateResult<'tcx, ty::GenericArgsRef<'tcx>> { if self.ambient_variance == ty::Variance::Invariant { // Avoid fetching the variance if we are in an invariant // context; no need, and it can induce dependency cycles // (e.g., #41849). relate_args_invariantly(self, a_arg, b_arg) } else { let tcx = self.tcx(); let opt_variances = tcx.variances_of(item_def_id); relate_args_with_variances(self, item_def_id, opt_variances, a_arg, b_arg, false) } } </ins> fn relate_with_variance<T: Relate<'tcx>>( &mut self, variance: ty::Variance,


<ins> //@ check-pass #![feature(inherent_associated_types)] //~^ WARN the feature `inherent_associated_types` is incomplete struct D<T> { a: T } impl<T: Default> D<T> { type Item = T; fn next() -> Self::Item { Self::Item::default() } } fn main() { } </ins>


<ins> warning: the feature `inherent_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/variance-computation-requires-equality.rs:3:12 | LL | #![feature(inherent_associated_types)] |            ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted </ins>


use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::InferOk; <ins> use rustc_infer::traits::query::NoSolution; </ins> use rustc_infer::traits::ObligationCause; use rustc_middle::middle::stability; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};


use rustc_target::abi::FieldIdx; use rustc_target::spec::abi::Abi::RustIntrinsic; use rustc_trait_selection::infer::InferCtxtExt; <ins> use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::ObligationCtxt; </ins> use rustc_trait_selection::traits::{self, ObligationCauseCode}; impl<'a, 'tcx> FnCtxt<'a, 'tcx> {


element_ty } None => { <ins> // Attempt to *shallowly* search for an impl which matches, // but has nested obligations which are unsatisfied. for (base_t, _) in self.autoderef(base.span, base_t).silence_errors() { if let Some((_, index_ty, element_ty)) = self.find_and_report_unsatisfied_index_impl(expr.hir_id, base, base_t) { self.demand_coerce(idx, idx_t, index_ty, None, AllowTwoPhase::No); return element_ty; } } </ins> let mut err = type_error_struct!( self.tcx.sess, expr.span,


} } <ins> /// Try to match an implementation of `Index` against a self type, and report /// the unsatisfied predicates that result from confirming this impl. /// /// Given an index expression, sometimes the `Self` type shallowly but does not /// deeply satisfy an impl predicate. Instead of simply saying that the type /// does not support being indexed, we want to point out exactly what nested /// predicates cause this to be, so that the user can add them to fix their code. fn find_and_report_unsatisfied_index_impl( &self, index_expr_hir_id: HirId, base_expr: &hir::Expr<'_>, base_ty: Ty<'tcx>, ) -> Option<(ErrorGuaranteed, Ty<'tcx>, Ty<'tcx>)> { let index_trait_def_id = self.tcx.lang_items().index_trait()?; let index_trait_output_def_id = self.tcx.get_diagnostic_item(sym::IndexOutput)?; let mut relevant_impls = vec![]; self.tcx.for_each_relevant_impl(index_trait_def_id, base_ty, |impl_def_id| { relevant_impls.push(impl_def_id); }); let [impl_def_id] = relevant_impls[..] else { // Only report unsatisfied impl predicates if there's one impl return None; }; self.commit_if_ok(|_| { let ocx = ObligationCtxt::new_in_snapshot(self); let impl_substs = self.fresh_substs_for_item(base_expr.span, impl_def_id); let impl_trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap().subst(self.tcx, impl_substs); let cause = self.misc(base_expr.span); // Match the impl self type against the base ty. If this fails, // we just skip this impl, since it's not particularly useful. let impl_trait_ref = ocx.normalize(&cause, self.param_env, impl_trait_ref); ocx.eq(&cause, self.param_env, impl_trait_ref.self_ty(), base_ty)?; // Register the impl's predicates. One of these predicates // must be unsatisfied, or else we wouldn't have gotten here // in the first place. ocx.register_obligations(traits::predicates_for_generics( |idx, span| { traits::ObligationCause::new( base_expr.span, self.body_id, if span.is_dummy() { traits::ExprItemObligation(impl_def_id, index_expr_hir_id, idx) } else { traits::ExprBindingObligation(impl_def_id, span, index_expr_hir_id, idx) }, ) }, self.param_env, self.tcx.predicates_of(impl_def_id).instantiate(self.tcx, impl_substs), )); // Normalize the output type, which we can use later on as the // return type of the index expression... let element_ty = ocx.normalize( &cause, self.param_env, self.tcx.mk_projection(index_trait_output_def_id, impl_trait_ref.substs), ); let errors = ocx.select_where_possible(); // There should be at least one error reported. If not, we // will still delay a span bug in `report_fulfillment_errors`. Ok::<_, NoSolution>(( self.err_ctxt().report_fulfillment_errors(&errors), impl_trait_ref.substs.type_at(1), element_ty, )) }) .ok() } </ins> fn point_at_index_if_possible( &self, errors: &mut Vec<traits::FulfillmentError<'tcx>>,


HashSet, Hasher, Implied, <ins> IndexOutput, </ins> Input, Into, IntoDiagnostic,


pub trait Index<Idx: ?Sized> { /// The returned type after indexing. #[stable(feature = "rust1", since = "1.0.0")] <ins> #[rustc_diagnostic_item = "IndexOutput"] </ins> type Output: ?Sized; /// Performs the indexing (`container[index]`) operation.


<ins> use std::hash::Hash; use std::marker::PhantomData; use std::ops::Index; struct HashMap<K, V>(PhantomData<(K, V)>); impl<K, V> Index<&K> for HashMap<K, V> where K: Hash, V: Copy, { type Output = V; fn index(&self, k: &K) -> &V { todo!() } } fn index<'a, K, V>(map: &'a HashMap<K, V>, k: K) -> &'a V { map[k] //~^ ERROR the trait bound `K: Hash` is not satisfied //~| ERROR the trait bound `V: Copy` is not satisfied //~| ERROR mismatched types //~| ERROR mismatched types } fn main() {} </ins>


<ins> error[E0277]: the trait bound `K: Hash` is not satisfied --> $DIR/bad-index-due-to-nested.rs:20:5 | LL |     map[k] |     ^^^ the trait `Hash` is not implemented for `K` | note: required by a bound in `<HashMap<K, V> as Index<&K>>` --> $DIR/bad-index-due-to-nested.rs:9:8 | LL |     K: Hash, |        ^^^^ required by this bound in `<HashMap<K, V> as Index<&K>>` help: consider restricting type parameter `K` | LL | fn index<'a, K: std::hash::Hash, V>(map: &'a HashMap<K, V>, k: K) -> &'a V { |               +++++++++++++++++ error[E0277]: the trait bound `V: Copy` is not satisfied --> $DIR/bad-index-due-to-nested.rs:20:5 | LL |     map[k] |     ^^^ the trait `Copy` is not implemented for `V` | note: required by a bound in `<HashMap<K, V> as Index<&K>>` --> $DIR/bad-index-due-to-nested.rs:10:8 | LL |     V: Copy, |        ^^^^ required by this bound in `<HashMap<K, V> as Index<&K>>` help: consider restricting type parameter `V` | LL | fn index<'a, K, V: std::marker::Copy>(map: &'a HashMap<K, V>, k: K) -> &'a V { |                  +++++++++++++++++++ error[E0308]: mismatched types --> $DIR/bad-index-due-to-nested.rs:20:9 | LL | fn index<'a, K, V>(map: &'a HashMap<K, V>, k: K) -> &'a V { |              - this type parameter LL |     map[k] |         ^ |         | |         expected `&K`, found type parameter `K` |         help: consider borrowing here: `&k` | = note:   expected reference `&K` found type parameter `K` error[E0308]: mismatched types --> $DIR/bad-index-due-to-nested.rs:20:5 | LL | fn index<'a, K, V>(map: &'a HashMap<K, V>, k: K) -> &'a V { |                 - this type parameter               ----- expected `&'a V` because of return type LL |     map[k] |     ^^^^^^ |     | |     expected `&V`, found type parameter `V` |     help: consider borrowing here: `&map[k]` | = note:   expected reference `&'a V` found type parameter `V` error: aborting due to 4 previous errors Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`. </ins>


Some(blk_id), ); if !fcx.tcx.features().unsized_locals { <del> unsized_return = self.is_return_ty_unsized(fcx, blk_id); </del> <ins> unsized_return = self.is_return_ty_definitely_unsized(fcx); </ins> } if let Some(expression) = expression && let hir::ExprKind::Loop(loop_blk, ..) = expression.kind {


None, ); if !fcx.tcx.features().unsized_locals { <del> let id = fcx.tcx.hir().parent_id(id); unsized_return = self.is_return_ty_unsized(fcx, id); </del> <ins> unsized_return = self.is_return_ty_definitely_unsized(fcx); </ins> } } _ => {


err.help("you could instead create a new `enum` with a variant for each returned type"); } <del> fn is_return_ty_unsized<'a>(&self, fcx: &FnCtxt<'a, 'tcx>, blk_id: hir::HirId) -> bool { if let Some((_, fn_decl, _)) = fcx.get_fn_decl(blk_id) && let hir::FnRetTy::Return(ty) = fn_decl.output && let ty = fcx.astconv().ast_ty_to_ty( ty) && let ty::Dynamic(..) = ty.kind() { return true; </del> <ins> /// Checks whether the return type is unsized via an obligation, which makes /// sure we consider `dyn Trait: Sized` where clauses, which are trivially /// false but technically valid for typeck. fn is_return_ty_definitely_unsized(&self, fcx: &FnCtxt<'_, 'tcx>) -> bool { if let Some(sig) = fcx.body_fn_sig() { !fcx.predicate_may_hold(&Obligation::new( fcx.tcx, ObligationCause::dummy(), fcx.param_env, ty::TraitRef::new( fcx.tcx, fcx.tcx.require_lang_item(hir::LangItem::Sized, None), [sig.output()], ), )) } else { false </ins> } <del> false </del> } pub fn complete<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Ty<'tcx> {


<ins> trait Trait<T> {} fn foo<T>() -> dyn Trait<T> where dyn Trait<T>: Sized, // pesky sized predicate { 42 //~^ ERROR mismatched types } fn main() {} </ins>


<ins> error[E0308]: mismatched types --> $DIR/return-dyn-type-mismatch-2.rs:7:5 | LL | fn foo<T>() -> dyn Trait<T> |                ------------ expected `(dyn Trait<T> + 'static)` because of return type ... LL |     42 |     ^^ expected `dyn Trait`, found integer | = note: expected trait object `(dyn Trait<T> + 'static)` found type `{integer}` error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. </ins>


<ins> pub trait TestTrait { type MyType; fn func() -> Option<Self> where Self: Sized; } impl<T> dyn TestTrait<MyType = T> where Self: Sized, // pesky sized predicate { fn other_func() -> dyn TestTrait<MyType = T> { match Self::func() { None => None, //~^ ERROR mismatched types } } } fn main() {} </ins>


<ins> error[E0308]: mismatched types --> $DIR/return-dyn-type-mismatch.rs:15:21 | LL |     fn other_func() -> dyn TestTrait<MyType = T> { |                        ------------------------- expected `(dyn TestTrait<MyType = T> + 'static)` because of return type LL |         match Self::func() { LL |             None => None, |                     ^^^^ expected `dyn TestTrait`, found `Option<_>` | = note: expected trait object `(dyn TestTrait<MyType = T> + 'static)` found enum `Option<_>` error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. </ins>


//! contains further primitive shared memory types, including [`atomic`] and //! [`mpsc`], which contains the channel types for message passing. //! <ins> //! # Use before and after `main()` //! //! Many parts of the standard library are expected to work before and after `main()`; //! but this is not guaranteed or ensured by tests. It is recommended that you write your own tests //! and run them on each platform you wish to support. //! This means that use of `std` before/after main, especially of features that interact with the //! OS or global state, is exempted from stability and portability guarantees and instead only //! provided on a best-effort basis. Nevertheless bug reports are appreciated. //! //! On the other hand `core` and `alloc` are most likely to work in such environments with //! the caveat that any hookable behavior such as panics, oom handling or allocators will also //! depend on the compatibility of the hooks. //! //! Some features may also behave differently outside main, e.g. stdio could become unbuffered, //! some panics might turn into aborts, backtraces might not get symbolicated or similar. //! //! Non-exhaustive list of known limitations: //! //! - after-main use of thread-locals, which also affects additional features: //!   - [`thread::current()`] //!   - [`thread::scope()`] //!   - [`sync::mpsc`] //! - before-main stdio file descriptors are not guaranteed to be open on unix platforms //! //! </ins> //! [I/O]: io //! [`MIN`]: i32::MIN //! [`MAX`]: i32::MAX


//! [rust-discord]: https://discord.gg/rust-lang //! [array]: prim@array //! [slice]: prim@slice // To run std tests without x.py without ending up with two copies of std, Miri needs to be // able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>. // rustc itself never sets the feature, so this line has no effect there.


This feature is unstable, so you can enable it by calling Rustdoc with the unstable `rustdoc-scrape-examples` flag: ```bash <del> cargo doc -Zunstable-options -Zrustdoc-scrape-examples=examples </del> <ins> cargo doc -Zunstable-options -Zrustdoc-scrape-examples </ins> ``` To enable this feature on [docs.rs](https://docs.rs), add this to your Cargo.toml: ```toml [package.metadata.docs.rs] <del> cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples=examples"] </del> <ins> cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"] </ins> ```


use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_errors::{Applicability, DiagnosticArgValue, DiagnosticId, IntoDiagnosticArg}; use rustc_hir::def::Namespace::{self, *}; <del> use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, PartialRes, PerNS}; </del> <ins> use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS}; </ins> use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::{BindingAnnotation, PrimTy, TraitCandidate}; use rustc_middle::middle::resolve_bound_vars::Set1;


} } <del> fn resolve_and_cache_rustdoc_path(&mut self, path_str: &str, ns: Namespace) -> bool { </del> <ins> fn resolve_and_cache_rustdoc_path(&mut self, path_str: &str, ns: Namespace) -> Option<Res> { </ins> // FIXME: This caching may be incorrect in case of multiple `macro_rules` // items with the same name in the same module. // Also hygiene is not considered. let mut doc_link_resolutions = std::mem::take(&mut self.r.doc_link_resolutions); <del> let res = doc_link_resolutions </del> <ins> let res = *doc_link_resolutions </ins> .entry(self.parent_scope.module.nearest_parent_mod().expect_local()) .or_default() .entry((Symbol::intern(path_str), ns))


return None; } res <del> }) .is_some(); </del> <ins> }); </ins> self.r.doc_link_resolutions = doc_link_resolutions; res }


let mut any_resolved = false; let mut need_assoc = false; for ns in [TypeNS, ValueNS, MacroNS] { <del> if self.resolve_and_cache_rustdoc_path(&path_str, ns) { any_resolved = true; </del> <ins> if let Some(res) = self.resolve_and_cache_rustdoc_path(&path_str, ns) { // Rustdoc ignores tool attribute resolutions and attempts // to resolve their prefixes for diagnostics. any_resolved = !matches!(res, Res::NonMacroAttr(NonMacroAttrKind::Tool)); </ins> } else if ns != MacroNS { need_assoc = true; }


Def(kind, id) => Ok(Res::Def(kind, id)), PrimTy(prim) => Ok(Res::Primitive(PrimitiveType::from_hir(prim))), // e.g. `#[derive]` <del> NonMacroAttr(..) | Err => Result::Err(()), </del> <ins> ToolMod | NonMacroAttr(..) | Err => Result::Err(()), </ins> other => bug!("unrecognized res {:?}", other), } }


<ins> // Regression test for <https://github.com/rust-lang/rust/issues/111189>. // This test ensures that it doesn't crash. #![deny(warnings)] /// #[rustfmt::skip] //~^ ERROR unresolved link to `rustfmt::skip` /// #[clippy::whatever] //~^ ERROR unresolved link to `clippy::whatever` pub fn foo() {} </ins>


<ins> error: unresolved link to `rustfmt::skip` --> $DIR/issue-111189-resolution-ice.rs:6:7 | LL | /// #[rustfmt::skip] |       ^^^^^^^^^^^^^ no item named `rustfmt` in scope | note: the lint level is defined here --> $DIR/issue-111189-resolution-ice.rs:4:9 | LL | #![deny(warnings)] |         ^^^^^^^^ = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(warnings)]` error: unresolved link to `clippy::whatever` --> $DIR/issue-111189-resolution-ice.rs:8:7 | LL | /// #[clippy::whatever] |       ^^^^^^^^^^^^^^^^ no item named `clippy` in scope error: aborting due to 2 previous errors </ins>


) -> Result<std::ops::Range<BasicBlock>, &'static str> { let callee_attrs = self.tcx.codegen_fn_attrs(callsite.callee.def_id()); self.check_codegen_attributes(callsite, callee_attrs)?; <ins> let terminator = caller_body[callsite.block].terminator.as_ref().unwrap(); let TerminatorKind::Call { args, destination, .. } = &terminator.kind else { bug!() }; let destination_ty = destination.ty(&caller_body.local_decls, self.tcx).ty; for arg in args { if !arg.ty(&caller_body.local_decls, self.tcx).is_sized(self.tcx, self.param_env) { // We do not allow inlining functions with unsized params. Inlining these functions // could create unsized locals, which are unsound and being phased out. return Err("Call has unsized argument"); } } </ins> self.check_mir_is_available(caller_body, &callsite.callee)?; let callee_body = try_instance_mir(self.tcx, callsite.callee.def)?; self.check_mir_body(callsite, callee_body, callee_attrs)?;


// Check call signature compatibility. // Normally, this shouldn't be required, but trait normalization failure can create a // validation ICE. <del> let terminator = caller_body[callsite.block].terminator.as_ref().unwrap(); let TerminatorKind::Call { args, destination, .. } = &terminator.kind else { bug!() }; let destination_ty = destination.ty(&caller_body.local_decls, self.tcx).ty; </del> let output_type = callee_body.return_ty(); if !util::is_subtype(self.tcx, self.param_env, output_type, destination_ty) { trace!(?output_type, ?destination_ty);


<ins> - // MIR for `caller` before Inline + // MIR for `caller` after Inline fn caller(_1: Box<[i32]>) -> () { debug x => _1;                       // in scope 0 at $DIR/unsized_argument.rs:+0:11: +0:12 let mut _0: ();                      // return place in scope 0 at $DIR/unsized_argument.rs:+0:26: +0:26 let _2: ();                          // in scope 0 at $DIR/unsized_argument.rs:+1:5: +1:15 let mut _3: std::boxed::Box<[i32]>;  // in scope 0 at $DIR/unsized_argument.rs:+1:13: +1:14 let mut _4: ();                      // in scope 0 at $DIR/unsized_argument.rs:+1:14: +1:15 let mut _5: ();                      // in scope 0 at $DIR/unsized_argument.rs:+1:14: +1:15 let mut _6: ();                      // in scope 0 at $DIR/unsized_argument.rs:+1:14: +1:15 let mut _7: *const [i32];            // in scope 0 at $DIR/unsized_argument.rs:+1:13: +1:14 bb0: { StorageLive(_2);                 // scope 0 at $DIR/unsized_argument.rs:+1:5: +1:15 StorageLive(_3);                 // scope 0 at $DIR/unsized_argument.rs:+1:13: +1:14 _3 = move _1;                    // scope 0 at $DIR/unsized_argument.rs:+1:13: +1:14 _7 = (((_3.0: std::ptr::Unique<[i32]>).0: std::ptr::NonNull<[i32]>).0: *const [i32]); // scope 0 at $DIR/unsized_argument.rs:+1:5: +1:15 _2 = callee(move (*_7)) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/unsized_argument.rs:+1:5: +1:15 // mir::Constant // + span: $DIR/unsized_argument.rs:9:5: 9:11 // + literal: Const { ty: fn([i32]) {callee}, val: Value(<ZST>) } } bb1: { StorageDead(_3);                 // scope 0 at $DIR/unsized_argument.rs:+1:14: +1:15 StorageDead(_2);                 // scope 0 at $DIR/unsized_argument.rs:+1:15: +1:16 _0 = const ();                   // scope 0 at $DIR/unsized_argument.rs:+0:26: +2:2 return;                          // scope 0 at $DIR/unsized_argument.rs:+2:2: +2:2 } bb2 (cleanup): { resume;                          // scope 0 at $DIR/unsized_argument.rs:+0:1: +2:2 } bb3: { _4 = alloc::alloc::box_free::<[i32], std::alloc::Global>(move (_3.0: std::ptr::Unique<[i32]>), move (_3.1: std::alloc::Global)) -> bb1; // scope 0 at $DIR/unsized_argument.rs:+1:14: +1:15 // mir::Constant // + span: $DIR/unsized_argument.rs:9:14: 9:15 // + literal: Const { ty: unsafe fn(Unique<[i32]>, std::alloc::Global) {alloc::alloc::box_free::<[i32], std::alloc::Global>}, val: Value(<ZST>) } } bb4 (cleanup): { _6 = alloc::alloc::box_free::<[i32], std::alloc::Global>(move (_3.0: std::ptr::Unique<[i32]>), move (_3.1: std::alloc::Global)) -> [return: bb2, unwind terminate]; // scope 0 at $DIR/unsized_argument.rs:+1:14: +1:15 // mir::Constant // + span: $DIR/unsized_argument.rs:9:14: 9:15 // + literal: Const { ty: unsafe fn(Unique<[i32]>, std::alloc::Global) {alloc::alloc::box_free::<[i32], std::alloc::Global>}, val: Value(<ZST>) } } } </ins>


<ins> // needs-unwind #![feature(unsized_fn_params)] #[inline(always)] fn callee(y: [i32]) {} // EMIT_MIR unsized_argument.caller.Inline.diff fn caller(x: Box<[i32]>) { callee(*x); } fn main() { let b = Box::new([1]); caller(b); } </ins>


} } <del> /// Whether `check_binop` allows overloaded operators to be invoked. </del> <ins> /// Whether `check_binop` is part of an assignment or not. /// Used to know wether we allow user overloads and to print /// better messages on error. </ins> #[deriving(Eq)] <del> enum AllowOverloadedOperatorsFlag { AllowOverloadedOperators, DontAllowOverloadedOperators, </del> <ins> enum IsBinopAssignment{ SimpleBinop, BinopAssignment, </ins> } #[deriving(Clone)]


rhs: @ast::Expr, // Used only in the error case expected_result: Option<ty::t>, <del> allow_overloaded_operators: AllowOverloadedOperatorsFlag </del> <ins> is_binop_assignment: IsBinopAssignment </ins> ) { let tcx = fcx.ccx.tcx;


} <del> // Check for overloaded operators if allowed. </del> <ins> // Check for overloaded operators if not an assignment. </ins> let result_t; <del> if allow_overloaded_operators == AllowOverloadedOperators { </del> <ins> if is_binop_assignment == SimpleBinop { </ins> result_t = check_user_binop(fcx, callee_id, expr,


} else { fcx.type_error_message(expr.span, |actual| { <del> format!("binary operation {} cannot be  applied to type `{}`", ast_util::binop_to_str(op), actual) </del> <ins> format!("binary assignment operation  {}= cannot be applied to type `{}`", ast_util::binop_to_str(op), actual) </ins> }, lhs_t, None); <ins> check_expr(fcx, rhs); </ins> result_t = ty::mk_err(); }


lhs, rhs, expected, <del> AllowOverloadedOperators); </del> <ins> SimpleBinop); </ins> let lhs_ty = fcx.expr_ty(lhs); let rhs_ty = fcx.expr_ty(rhs);


lhs, rhs, expected, <del> DontAllowOverloadedOperators); </del> <ins> BinopAssignment); </ins> let lhs_t = fcx.expr_ty(lhs); let result_t = fcx.expr_ty(expr);


<ins> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. struct Foo; fn main() { let mut a = Foo; let ref b = Foo; a += *b; //~ Error: binary assignment operation += cannot be applied to type `Foo` } </ins>


// Regression test for issue #5239 fn main() { <del> let x: |int| -> int = |ref x| { x += 1; }; //~ ERROR binary operation + cannot be applied to type `&int` </del> <ins> let x: |int| -> int = |ref x| { x += 1; }; //~ ERROR binary assignment operation += cannot be applied to type `&int` </ins> }


} } <ins> all_native_libs.extend_from_slice(&codegen_results.crate_info.used_libraries); </ins> if sess.opts.prints.contains(&PrintRequest::NativeStaticLibs) { print_native_static_libs(sess, &all_native_libs, &all_rust_dylibs); }


<ins> include ../tools.mk # ignore-cross-compile # ignore-wasm all: $(RUSTC) --crate-type rlib -lbar_cli bar.rs $(RUSTC) foo.rs -lfoo_cli --crate-type staticlib --print native-static-libs 2>&1  | grep 'note: native-static-libs: '  | sed 's/note: native-static-libs: (.*)/1/' > $(TMPDIR)/libs.txt cat $(TMPDIR)/libs.txt | grep -F "glib-2.0" # in bar.rs cat $(TMPDIR)/libs.txt | grep -F "systemd" # in foo.rs cat $(TMPDIR)/libs.txt | grep -F "bar_cli" cat $(TMPDIR)/libs.txt | grep -F "foo_cli" </ins>


<ins> #[no_mangle] pub extern "C" fn my_bar_add(left: i32, right: i32) -> i32 { // Obviously makes no sense but... unsafe { g_free(std::ptr::null_mut()); } left + right } #[link(name = "glib-2.0")] extern "C" { fn g_free(p: *mut ()); } </ins>


<ins> extern crate bar; #[no_mangle] pub extern "C" fn my_foo_add(left: i32, right: i32) -> i32 { // Obviously makes no sense but... unsafe { init(std::ptr::null_mut()); } bar::my_bar_add(left, right) } #[link(name = "systemd")] extern "C" { fn init(p: *mut ()); } </ins>


<ins> #![feature(inherent_associated_types)] #![allow(incomplete_features)] // Check that we don't crash when printing inherent projections in diagnostics. pub struct Carrier<'a>(&'a ()); pub type User = for<'b> fn(Carrier<'b>::Focus<i32>); impl<'a> Carrier<'a> { pub type Focus<T> = &'a mut User; //~ ERROR overflow evaluating associated type } fn main() {} </ins>


<ins> error: overflow evaluating associated type `Carrier<'b>::Focus<i32>` --> $DIR/issue-111879-0.rs:11:25 | LL |     pub type Focus<T> = &'a mut User; |                         ^^^^^^^^^^^^ error: aborting due to previous error </ins>


<ins> #![feature(inherent_associated_types)] #![allow(incomplete_features)] // Check that we don't crash when printing inherent projections in diagnostics. struct Foo<T>(T); impl<'a> Foo<fn(&'a ())> { type Assoc = &'a (); } fn main(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {} //~ ERROR `main` function has wrong type </ins>


<ins> error[E0580]: `main` function has wrong type --> $DIR/issue-111879-1.rs:12:1 | LL | fn main(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters | = note: expected fn pointer `fn()` found fn pointer `fn(for<'a> fn(Foo<fn(&'a ())>::Assoc))` error: aborting due to previous error For more information about this error, try `rustc --explain E0580`. </ins>


continue; } <del> let is_closure = matches!(arg.kind, ExprKind::Closure { .. }); </del> <ins> // For this check, we do *not* want to treat async generator closures (async blocks) // as proper closures. Doing so would regress type inference when feeding // the return value of an argument-position async block to an argument-position // closure wrapped in a block. // See <https://github.com/rust-lang/rust/issues/112225>. let is_closure = if let ExprKind::Closure(closure) = arg.kind { !tcx.generator_is_async(closure.def_id.to_def_id()) } else { false }; </ins> if is_closure != check_closures { continue; }


<ins> // check-pass // edition:2021 use core::future::Future; fn main() { do_async(async { (0,) }, { // closure must be inside block |info| println!("{:?}", info.0) }); } fn do_async<R, Fut, F>(_tokio_fut: Fut, _glib_closure: F) where Fut: Future<Output = R>, F: FnOnce(R), { } </ins>


<ins> // edition:2021 // With the current compiler logic, we cannot have both the `112225-1` case, // and this `112225-2` case working, as the type inference depends on the evaluation // order, and there is some explicit ordering going on. // See the `check_closures` part in `FnCtxt::check_argument_types`. // The `112225-1` case was a regression in real world code, whereas the `112225-2` // case never used to work prior to 1.70. use core::future::Future; fn main() { let x = Default::default(); //~^ ERROR: type annotations needed do_async( async { x.0; }, { || { let _: &(i32,) = &x; } }, ); } fn do_async<Fut, T>(_fut: Fut, _val: T, ) {} </ins>


<ins> error[E0282]: type annotations needed --> $DIR/issue-112225-2.rs:13:9 | LL |     let x = Default::default(); |         ^ ... LL |         async { x.0; }, |                 - type must be known at this point | help: consider giving `x` an explicit type | LL |     let x: /* Type */ = Default::default(); |          ++++++++++++ error: aborting due to previous error For more information about this error, try `rustc --explain E0282`. </ins>


check::CargoMiri, check::MiroptTestTools, check::Rls, <del> check::RustAnalyzer, </del> check::Rustfmt, <ins> check::RustAnalyzer, </ins> check::Bootstrap ), Kind::Test => describe!(


impl Step for RustAnalyzer { type Output = (); const ONLY_HOSTS: bool = true; <del> const DEFAULT: bool = true; </del> <ins> const DEFAULT: bool = false; </ins> fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { run.path("src/tools/rust-analyzer")


if toml_val is not None: env["{}_{}".format(var_name, host_triple_sanitized)] = toml_val <ins> # In src/etc/rust_analyzer_settings.json, we configure rust-analyzer to # pass RUSTC_BOOTSTRAP=1 to all cargo invocations because the standard # library uses unstable Cargo features. Without RUSTC_BOOTSTRAP, # rust-analyzer would fail to fetch workspace layout when the system's # default toolchain is not nightly. # # But that setting has the collateral effect of rust-analyzer also # passing RUSTC_BOOTSTRAP=1 to all x.py invocations too (the various # overrideCommand). For compiling bootstrap, that is unwanted and can # cause spurious rebuilding of bootstrap when rust-analyzer x.py # invocations are interleaved with handwritten ones on the command line. env.pop("RUSTC_BOOTSTRAP", None) </ins> # preserve existing RUSTFLAGS env.setdefault("RUSTFLAGS", "")


} #[test] <ins> #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn connect_timeout_error() { let socket_addr = next_test_ip4(); let result = TcpStream::connect_timeout(&socket_addr, Duration::MAX); assert!(!matches!(result, Err(e) if e.kind() == ErrorKind::TimedOut)); let _listener = TcpListener::bind(&socket_addr).unwrap(); assert!(TcpStream::connect_timeout(&socket_addr, Duration::MAX).is_ok()); } #[test] </ins> fn listen_localhost() { let socket_addr = next_test_ip4(); let listener = t!(TcpListener::bind(&socket_addr));


} let mut timeout = c::timeval { <del> tv_sec: timeout.as_secs() as c_long, </del> <ins> tv_sec: cmp::min(timeout.as_secs(), c_long::MAX as u64) as c_long, </ins> tv_usec: (timeout.subsec_nanos() / 1000) as c_long, };


} let mut new_abis = Vec::new(); <del> loop { </del> <ins> while !p.eat(&token::CloseDelim(Delimiter::Parenthesis)) { </ins> match p.parse_str_lit() { Ok(str_lit) => { new_abis.push((str_lit.symbol_unescaped, str_lit.span)); } Err(opt_lit) => { <del> // If the non-string literal is a closing paren then it's the end of the list and is fine if p.eat(&token::CloseDelim(Delimiter::Parenthesis)) { break; } </del> let span = opt_lit.map_or(p.token.span, |lit| lit.span); let mut err = p.sess.span_diagnostic.struct_span_err(span, "expected string literal");


<ins> // needs-asm-support #![feature(asm_const)] use std::arch::{asm, global_asm}; fn main() { let mut foo = 0; let mut bar = 0; unsafe { asm!(); //~^ ERROR requires at least a template string argument asm!(foo); //~^ ERROR asm template must be a string literal asm!("{}" foo); //~^ ERROR expected token: `,` asm!("{}", foo); //~^ ERROR expected operand, clobber_abi, options, or additional template string asm!("{}", in foo); //~^ ERROR expected `(`, found `foo` asm!("{}", in(reg foo)); //~^ ERROR expected `)`, found `foo` asm!("{}", in(reg)); //~^ ERROR expected expression, found end of macro arguments asm!("{}", inout(=) foo => bar); //~^ ERROR expected register class or explicit register asm!("{}", inout(reg) foo =>); //~^ ERROR expected expression, found end of macro arguments asm!("{}", in(reg) foo => bar); //~^ ERROR expected one of `!`, `,`, `.`, `::`, `?`, `{`, or an operator, found `=>` asm!("{}", sym foo + bar); //~^ ERROR expected a path for argument to `sym` asm!("", options(foo)); //~^ ERROR expected one of asm!("", options(nomem foo)); //~^ ERROR expected one of asm!("", options(nomem, foo)); //~^ ERROR expected one of asm!("{}", options(), const foo); //~^ ERROR attempt to use a non-constant value in a constant // test that asm!'s clobber_abi doesn't accept non-string literals // see also https://github.com/rust-lang/rust/issues/112635 asm!("", clobber_abi()); //~^ ERROR at least one abi must be provided asm!("", clobber_abi(foo)); //~^ ERROR expected string literal asm!("", clobber_abi("C" foo)); //~^ ERROR expected one of `)` or `,`, found `foo` asm!("", clobber_abi("C", foo)); //~^ ERROR expected string literal asm!("", clobber_abi(1)); //~^ ERROR expected string literal asm!("", clobber_abi(())); //~^ ERROR expected string literal asm!("", clobber_abi(uwu)); //~^ ERROR expected string literal asm!("", clobber_abi({})); //~^ ERROR expected string literal asm!("", clobber_abi(loop {})); //~^ ERROR expected string literal asm!("", clobber_abi(if)); //~^ ERROR expected string literal asm!("", clobber_abi(do)); //~^ ERROR expected string literal asm!("", clobber_abi(<)); //~^ ERROR expected string literal asm!("", clobber_abi(.)); //~^ ERROR expected string literal asm!("{}", clobber_abi("C"), const foo); //~^ ERROR attempt to use a non-constant value in a constant asm!("", options(), clobber_abi("C")); asm!("{}", options(), clobber_abi("C"), const foo); //~^ ERROR attempt to use a non-constant value in a constant asm!("{a}", a = const foo, a = const bar); //~^ ERROR duplicate argument named `a` //~^^ ERROR argument never used //~^^^ ERROR attempt to use a non-constant value in a constant //~^^^^ ERROR attempt to use a non-constant value in a constant asm!("", options(), ""); //~^ ERROR expected one of asm!("{}", in(reg) foo, "{}", out(reg) foo); //~^ ERROR expected one of asm!(format!("{{{}}}", 0), in(reg) foo); //~^ ERROR asm template must be a string literal asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar); //~^ ERROR asm template must be a string literal asm!("{}", in(reg) _); //~^ ERROR _ cannot be used for input operands asm!("{}", inout(reg) _); //~^ ERROR _ cannot be used for input operands asm!("{}", inlateout(reg) _); //~^ ERROR _ cannot be used for input operands } } const FOO: i32 = 1; const BAR: i32 = 2; global_asm!(); //~^ ERROR requires at least a template string argument global_asm!(FOO); //~^ ERROR asm template must be a string literal global_asm!("{}" FOO); //~^ ERROR expected token: `,` global_asm!("{}", FOO); //~^ ERROR expected operand, options, or additional template string global_asm!("{}", const); //~^ ERROR expected expression, found end of macro arguments global_asm!("{}", const(reg) FOO); //~^ ERROR expected one of global_asm!("", options(FOO)); //~^ ERROR expected one of global_asm!("", options(nomem FOO)); //~^ ERROR expected one of global_asm!("", options(nomem, FOO)); //~^ ERROR expected one of global_asm!("{}", options(), const FOO); global_asm!("", clobber_abi(FOO)); //~^ ERROR expected string literal global_asm!("", clobber_abi("C" FOO)); //~^ ERROR expected one of `)` or `,`, found `FOO` global_asm!("", clobber_abi("C", FOO)); //~^ ERROR expected string literal global_asm!("{}", clobber_abi("C"), const FOO); //~^ ERROR `clobber_abi` cannot be used with `global_asm!` global_asm!("", options(), clobber_abi("C")); //~^ ERROR `clobber_abi` cannot be used with `global_asm!` global_asm!("{}", options(), clobber_abi("C"), const FOO); //~^ ERROR `clobber_abi` cannot be used with `global_asm!` global_asm!("", clobber_abi("C"), clobber_abi("C")); //~^ ERROR `clobber_abi` cannot be used with `global_asm!` global_asm!("{a}", a = const FOO, a = const BAR); //~^ ERROR duplicate argument named `a` //~^^ ERROR argument never used global_asm!("", options(), ""); //~^ ERROR expected one of global_asm!("{}", const FOO, "{}", const FOO); //~^ ERROR expected one of global_asm!(format!("{{{}}}", 0), const FOO); //~^ ERROR asm template must be a string literal global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR); //~^ ERROR asm template must be a string literal </ins>


<ins> error: requires at least a template string argument --> $DIR/parse-error.rs:11:9 | LL |         asm!(); |         ^^^^^^ error: asm template must be a string literal --> $DIR/parse-error.rs:13:14 | LL |         asm!(foo); |              ^^^ error: expected token: `,` --> $DIR/parse-error.rs:15:19 | LL |         asm!("{}" foo); |                   ^^^ expected `,` error: expected operand, clobber_abi, options, or additional template string --> $DIR/parse-error.rs:17:20 | LL |         asm!("{}", foo); |                    ^^^ expected operand, clobber_abi, options, or additional template string error: expected `(`, found `foo` --> $DIR/parse-error.rs:19:23 | LL |         asm!("{}", in foo); |                       ^^^ expected `(` error: expected `)`, found `foo` --> $DIR/parse-error.rs:21:27 | LL |         asm!("{}", in(reg foo)); |                           ^^^ expected `)` error: expected expression, found end of macro arguments --> $DIR/parse-error.rs:23:27 | LL |         asm!("{}", in(reg)); |                           ^ expected expression error: expected register class or explicit register --> $DIR/parse-error.rs:25:26 | LL |         asm!("{}", inout(=) foo => bar); |                          ^ error: expected expression, found end of macro arguments --> $DIR/parse-error.rs:27:37 | LL |         asm!("{}", inout(reg) foo =>); |                                     ^ expected expression error: expected one of `!`, `,`, `.`, `::`, `?`, `{`, or an operator, found `=>` --> $DIR/parse-error.rs:29:32 | LL |         asm!("{}", in(reg) foo => bar); |                                ^^ expected one of 7 possible tokens error: expected a path for argument to `sym` --> $DIR/parse-error.rs:31:24 | LL |         asm!("{}", sym foo + bar); |                        ^^^^^^^^^ error: expected one of `)`, `att_syntax`, `may_unwind`, `nomem`, `noreturn`, `nostack`, `preserves_flags`, `pure`, `raw`, or `readonly`, found `foo` --> $DIR/parse-error.rs:33:26 | LL |         asm!("", options(foo)); |                          ^^^ expected one of 10 possible tokens error: expected one of `)` or `,`, found `foo` --> $DIR/parse-error.rs:35:32 | LL |         asm!("", options(nomem foo)); |                                ^^^ expected one of `)` or `,` error: expected one of `)`, `att_syntax`, `may_unwind`, `nomem`, `noreturn`, `nostack`, `preserves_flags`, `pure`, `raw`, or `readonly`, found `foo` --> $DIR/parse-error.rs:37:33 | LL |         asm!("", options(nomem, foo)); |                                 ^^^ expected one of 10 possible tokens error: at least one abi must be provided as an argument to `clobber_abi` --> $DIR/parse-error.rs:44:30 | LL |         asm!("", clobber_abi()); |                              ^ error: expected string literal --> $DIR/parse-error.rs:46:30 | LL |         asm!("", clobber_abi(foo)); |                              ^^^ not a string literal error: expected one of `)` or `,`, found `foo` --> $DIR/parse-error.rs:48:34 | LL |         asm!("", clobber_abi("C" foo)); |                                  ^^^ expected one of `)` or `,` error: expected string literal --> $DIR/parse-error.rs:50:35 | LL |         asm!("", clobber_abi("C", foo)); |                                   ^^^ not a string literal error: expected string literal --> $DIR/parse-error.rs:52:30 | LL |         asm!("", clobber_abi(1)); |                              ^ not a string literal error: expected string literal --> $DIR/parse-error.rs:54:30 | LL |         asm!("", clobber_abi(())); |                              ^ not a string literal error: expected string literal --> $DIR/parse-error.rs:56:30 | LL |         asm!("", clobber_abi(uwu)); |                              ^^^ not a string literal error: expected string literal --> $DIR/parse-error.rs:58:30 | LL |         asm!("", clobber_abi({})); |                              ^ not a string literal error: expected string literal --> $DIR/parse-error.rs:60:30 | LL |         asm!("", clobber_abi(loop {})); |                              ^^^^ not a string literal error: expected string literal --> $DIR/parse-error.rs:62:30 | LL |         asm!("", clobber_abi(if)); |                              ^^ not a string literal error: expected string literal --> $DIR/parse-error.rs:64:30 | LL |         asm!("", clobber_abi(do)); |                              ^^ not a string literal error: expected string literal --> $DIR/parse-error.rs:66:30 | LL |         asm!("", clobber_abi(<)); |                              ^ not a string literal error: expected string literal --> $DIR/parse-error.rs:68:30 | LL |         asm!("", clobber_abi(.)); |                              ^ not a string literal error: duplicate argument named `a` --> $DIR/parse-error.rs:76:36 | LL |         asm!("{a}", a = const foo, a = const bar); |                     -------------  ^^^^^^^^^^^^^ duplicate argument |                     | |                     previously here error: argument never used --> $DIR/parse-error.rs:76:36 | LL |         asm!("{a}", a = const foo, a = const bar); |                                    ^^^^^^^^^^^^^ argument never used | = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"` error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `lateout`, `options`, `out`, or `sym`, found `""` --> $DIR/parse-error.rs:82:29 | LL |         asm!("", options(), ""); |                             ^^ expected one of 9 possible tokens error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `lateout`, `options`, `out`, or `sym`, found `"{}"` --> $DIR/parse-error.rs:84:33 | LL |         asm!("{}", in(reg) foo, "{}", out(reg) foo); |                                 ^^^^ expected one of 9 possible tokens error: asm template must be a string literal --> $DIR/parse-error.rs:86:14 | LL |         asm!(format!("{{{}}}", 0), in(reg) foo); |              ^^^^^^^^^^^^^^^^^^^^ | = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error: asm template must be a string literal --> $DIR/parse-error.rs:88:21 | LL |         asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar); |                     ^^^^^^^^^^^^^^^^^^^^ | = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error: _ cannot be used for input operands --> $DIR/parse-error.rs:90:28 | LL |         asm!("{}", in(reg) _); |                            ^ error: _ cannot be used for input operands --> $DIR/parse-error.rs:92:31 | LL |         asm!("{}", inout(reg) _); |                               ^ error: _ cannot be used for input operands --> $DIR/parse-error.rs:94:35 | LL |         asm!("{}", inlateout(reg) _); |                                   ^ error: requires at least a template string argument --> $DIR/parse-error.rs:101:1 | LL | global_asm!(); | ^^^^^^^^^^^^^ error: asm template must be a string literal --> $DIR/parse-error.rs:103:13 | LL | global_asm!(FOO); |             ^^^ error: expected token: `,` --> $DIR/parse-error.rs:105:18 | LL | global_asm!("{}" FOO); |                  ^^^ expected `,` error: expected operand, options, or additional template string --> $DIR/parse-error.rs:107:19 | LL | global_asm!("{}", FOO); |                   ^^^ expected operand, options, or additional template string error: expected expression, found end of macro arguments --> $DIR/parse-error.rs:109:24 | LL | global_asm!("{}", const); |                        ^ expected expression error: expected one of `,`, `.`, `?`, or an operator, found `FOO` --> $DIR/parse-error.rs:111:30 | LL | global_asm!("{}", const(reg) FOO); |                              ^^^ expected one of `,`, `.`, `?`, or an operator error: expected one of `)`, `att_syntax`, or `raw`, found `FOO` --> $DIR/parse-error.rs:113:25 | LL | global_asm!("", options(FOO)); |                         ^^^ expected one of `)`, `att_syntax`, or `raw` error: expected one of `)`, `att_syntax`, or `raw`, found `nomem` --> $DIR/parse-error.rs:115:25 | LL | global_asm!("", options(nomem FOO)); |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw` error: expected one of `)`, `att_syntax`, or `raw`, found `nomem` --> $DIR/parse-error.rs:117:25 | LL | global_asm!("", options(nomem, FOO)); |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw` error: expected string literal --> $DIR/parse-error.rs:120:29 | LL | global_asm!("", clobber_abi(FOO)); |                             ^^^ not a string literal error: expected one of `)` or `,`, found `FOO` --> $DIR/parse-error.rs:122:33 | LL | global_asm!("", clobber_abi("C" FOO)); |                                 ^^^ expected one of `)` or `,` error: expected string literal --> $DIR/parse-error.rs:124:34 | LL | global_asm!("", clobber_abi("C", FOO)); |                                  ^^^ not a string literal error: `clobber_abi` cannot be used with `global_asm!` --> $DIR/parse-error.rs:126:19 | LL | global_asm!("{}", clobber_abi("C"), const FOO); |                   ^^^^^^^^^^^^^^^^ error: `clobber_abi` cannot be used with `global_asm!` --> $DIR/parse-error.rs:128:28 | LL | global_asm!("", options(), clobber_abi("C")); |                            ^^^^^^^^^^^^^^^^ error: `clobber_abi` cannot be used with `global_asm!` --> $DIR/parse-error.rs:130:30 | LL | global_asm!("{}", options(), clobber_abi("C"), const FOO); |                              ^^^^^^^^^^^^^^^^ error: `clobber_abi` cannot be used with `global_asm!` --> $DIR/parse-error.rs:132:17 | LL | global_asm!("", clobber_abi("C"), clobber_abi("C")); |                 ^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^ error: duplicate argument named `a` --> $DIR/parse-error.rs:134:35 | LL | global_asm!("{a}", a = const FOO, a = const BAR); |                    -------------  ^^^^^^^^^^^^^ duplicate argument |                    | |                    previously here error: argument never used --> $DIR/parse-error.rs:134:35 | LL | global_asm!("{a}", a = const FOO, a = const BAR); |                                   ^^^^^^^^^^^^^ argument never used | = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"` error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `""` --> $DIR/parse-error.rs:137:28 | LL | global_asm!("", options(), ""); |                            ^^ expected one of `clobber_abi`, `const`, `options`, or `sym` error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `"{}"` --> $DIR/parse-error.rs:139:30 | LL | global_asm!("{}", const FOO, "{}", const FOO); |                              ^^^^ expected one of `clobber_abi`, `const`, `options`, or `sym` error: asm template must be a string literal --> $DIR/parse-error.rs:141:13 | LL | global_asm!(format!("{{{}}}", 0), const FOO); |             ^^^^^^^^^^^^^^^^^^^^ | = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error: asm template must be a string literal --> $DIR/parse-error.rs:143:20 | LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR); |                    ^^^^^^^^^^^^^^^^^^^^ | = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0435]: attempt to use a non-constant value in a constant --> $DIR/parse-error.rs:39:37 | LL |     let mut foo = 0; |     ----------- help: consider using `const` instead of `let`: `const foo` ... LL |         asm!("{}", options(), const foo); |                                     ^^^ non-constant value error[E0435]: attempt to use a non-constant value in a constant --> $DIR/parse-error.rs:71:44 | LL |     let mut foo = 0; |     ----------- help: consider using `const` instead of `let`: `const foo` ... LL |         asm!("{}", clobber_abi("C"), const foo); |                                            ^^^ non-constant value error[E0435]: attempt to use a non-constant value in a constant --> $DIR/parse-error.rs:74:55 | LL |     let mut foo = 0; |     ----------- help: consider using `const` instead of `let`: `const foo` ... LL |         asm!("{}", options(), clobber_abi("C"), const foo); |                                                       ^^^ non-constant value error[E0435]: attempt to use a non-constant value in a constant --> $DIR/parse-error.rs:76:31 | LL |     let mut foo = 0; |     ----------- help: consider using `const` instead of `let`: `const foo` ... LL |         asm!("{a}", a = const foo, a = const bar); |                               ^^^ non-constant value error[E0435]: attempt to use a non-constant value in a constant --> $DIR/parse-error.rs:76:46 | LL |     let mut bar = 0; |     ----------- help: consider using `const` instead of `let`: `const bar` ... LL |         asm!("{a}", a = const foo, a = const bar); |                                              ^^^ non-constant value error: aborting due to 63 previous errors For more information about this error, try `rustc --explain E0435`. </ins>


<del> // only-x86_64 #![feature(asm_const)] use std::arch::{asm, global_asm}; fn main() { let mut foo = 0; let mut bar = 0; unsafe { asm!(); //~^ ERROR requires at least a template string argument asm!(foo); //~^ ERROR asm template must be a string literal asm!("{}" foo); //~^ ERROR expected token: `,` asm!("{}", foo); //~^ ERROR expected operand, clobber_abi, options, or additional template string asm!("{}", in foo); //~^ ERROR expected `(`, found `foo` asm!("{}", in(reg foo)); //~^ ERROR expected `)`, found `foo` asm!("{}", in(reg)); //~^ ERROR expected expression, found end of macro arguments asm!("{}", inout(=) foo => bar); //~^ ERROR expected register class or explicit register asm!("{}", inout(reg) foo =>); //~^ ERROR expected expression, found end of macro arguments asm!("{}", in(reg) foo => bar); //~^ ERROR expected one of `!`, `,`, `.`, `::`, `?`, `{`, or an operator, found `=>` asm!("{}", sym foo + bar); //~^ ERROR expected a path for argument to `sym` asm!("", options(foo)); //~^ ERROR expected one of asm!("", options(nomem foo)); //~^ ERROR expected one of asm!("", options(nomem, foo)); //~^ ERROR expected one of asm!("{}", options(), const foo); //~^ ERROR attempt to use a non-constant value in a constant asm!("", clobber_abi()); //~^ ERROR at least one abi must be provided asm!("", clobber_abi(foo)); //~^ ERROR expected string literal asm!("", clobber_abi("C" foo)); //~^ ERROR expected one of `)` or `,`, found `foo` asm!("", clobber_abi("C", foo)); //~^ ERROR expected string literal asm!("{}", clobber_abi("C"), const foo); //~^ ERROR attempt to use a non-constant value in a constant asm!("", options(), clobber_abi("C")); asm!("{}", options(), clobber_abi("C"), const foo); //~^ ERROR attempt to use a non-constant value in a constant asm!("{a}", a = const foo, a = const bar); //~^ ERROR duplicate argument named `a` //~^^ ERROR argument never used //~^^^ ERROR attempt to use a non-constant value in a constant //~^^^^ ERROR attempt to use a non-constant value in a constant asm!("", a = in("eax") foo); //~^ ERROR explicit register arguments cannot have names asm!("{a}", in("eax") foo, a = const bar); //~^ ERROR attempt to use a non-constant value in a constant asm!("{a}", in("eax") foo, a = const bar); //~^ ERROR attempt to use a non-constant value in a constant asm!("{1}", in("eax") foo, const bar); //~^ ERROR positional arguments cannot follow named arguments or explicit register arguments //~^^ ERROR attempt to use a non-constant value in a constant asm!("", options(), ""); //~^ ERROR expected one of asm!("{}", in(reg) foo, "{}", out(reg) foo); //~^ ERROR expected one of asm!(format!("{{{}}}", 0), in(reg) foo); //~^ ERROR asm template must be a string literal asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar); //~^ ERROR asm template must be a string literal asm!("{}", in(reg) _); //~^ ERROR _ cannot be used for input operands asm!("{}", inout(reg) _); //~^ ERROR _ cannot be used for input operands asm!("{}", inlateout(reg) _); //~^ ERROR _ cannot be used for input operands } } const FOO: i32 = 1; const BAR: i32 = 2; global_asm!(); //~^ ERROR requires at least a template string argument global_asm!(FOO); //~^ ERROR asm template must be a string literal global_asm!("{}" FOO); //~^ ERROR expected token: `,` global_asm!("{}", FOO); //~^ ERROR expected operand, options, or additional template string global_asm!("{}", const); //~^ ERROR expected expression, found end of macro arguments global_asm!("{}", const(reg) FOO); //~^ ERROR expected one of global_asm!("", options(FOO)); //~^ ERROR expected one of global_asm!("", options(nomem FOO)); //~^ ERROR expected one of global_asm!("", options(nomem, FOO)); //~^ ERROR expected one of global_asm!("{}", options(), const FOO); global_asm!("", clobber_abi(FOO)); //~^ ERROR expected string literal global_asm!("", clobber_abi("C" FOO)); //~^ ERROR expected one of `)` or `,`, found `FOO` global_asm!("", clobber_abi("C", FOO)); //~^ ERROR expected string literal global_asm!("{}", clobber_abi("C"), const FOO); //~^ ERROR `clobber_abi` cannot be used with `global_asm!` global_asm!("", options(), clobber_abi("C")); //~^ ERROR `clobber_abi` cannot be used with `global_asm!` global_asm!("{}", options(), clobber_abi("C"), const FOO); //~^ ERROR `clobber_abi` cannot be used with `global_asm!` global_asm!("", clobber_abi("C"), clobber_abi("C")); //~^ ERROR `clobber_abi` cannot be used with `global_asm!` global_asm!("{a}", a = const FOO, a = const BAR); //~^ ERROR duplicate argument named `a` //~^^ ERROR argument never used global_asm!("", options(), ""); //~^ ERROR expected one of global_asm!("{}", const FOO, "{}", const FOO); //~^ ERROR expected one of global_asm!(format!("{{{}}}", 0), const FOO); //~^ ERROR asm template must be a string literal global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR); //~^ ERROR asm template must be a string literal </del>