<ins> error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/issue-80779.rs:10:28 | LL | pub fn g(_: T<'static>) -> _ {} |                            ^ |                            | |                            not allowed in type signatures |                            help: replace with the correct return type: `()` error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/issue-80779.rs:5:29 | LL | pub fn f<'a>(val: T<'a>) -> _ { |                             ^ |                             | |                             not allowed in type signatures |                             help: replace with the correct return type: `()` error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0121`. </ins>


<del> A type parameter that is specified for `impl` is not constrained. </del> <ins> A type, const or lifetime parameter that is specified for `impl` is not constrained. </ins> Erroneous code example:


} ``` <del> Any type parameter of an `impl` must meet at least one of the following criteria: </del> <ins> Any type or const parameter of an `impl` must meet at least one of the following criteria: </ins> - it appears in the _implementing type_ of the impl, e.g. `impl<T> Foo<T>` - for a trait impl, it appears in the _implemented trait_, e.g.


- it is bound as an associated type, e.g. `impl<T, U> SomeTrait for T where T: AnotherTrait<AssocType=U>` <ins> Any unconstrained lifetime parameter of an `impl` is not supported if the lifetime parameter is used by an associated type. </ins> ### Error example 1 Suppose we have a struct `Foo` and we would like to define some methods for it.


(`Foo`) of the impl. In this case, we can fix the error by moving the type parameter from the `impl` to the method `get`: ``` struct Foo;


} ``` <ins> ### Error example 3 Suppose we have a struct `Foo` and we would like to define some methods for it. The following code example has a definition which leads to a compiler error: ```compile_fail,E0207 struct Foo; impl<const T: i32> Foo { // error: the const parameter `T` is not constrained by the impl trait, self // type, or predicates [E0207] fn get(&self) -> i32 { i32::default() } } ``` The problem is that the const parameter `T` does not appear in the implementing type (`Foo`) of the impl. In this case, we can fix the error by moving the type parameter from the `impl` to the method `get`: ``` struct Foo; // Move the const parameter from the impl to the method impl Foo { fn get<const T: i32>(&self) -> i32 { i32::default() } } ``` ### Error example 4 Suppose we have a struct `Foo` and a struct `Bar` that uses lifetime `'a`. We would like to implement trait `Contains` for `Foo`. The trait `Contains` have the associated type `B`. The following code example has a definition which leads to a compiler error: ```compile_fail,E0207 struct Foo; struct Bar<'a>; trait Contains { type B; fn get(&self) -> i32; } impl<'a> Contains for Foo { type B = Bar<'a>; // error: the lifetime parameter `'a` is not constrained by the impl trait, // self type, or predicates [E0207] fn get(&self) -> i32 { i32::default() } } ``` Please note that unconstrained lifetime parameters are not supported if they are being used by an associated type. </ins> ### Additional information For more information, please see [RFC 447].


); } else { // Trivial case: `T` needs an extra bound: `T: Bound`. <del> let (sp, suggestion) = match super_traits { None => predicate_constraint( </del> <ins> let (sp, suggestion) = match ( generics .params .iter() .filter( |p| !matches!(p.kind, hir::GenericParamKind::Type { synthetic: Some(_), ..}), ) .next(), super_traits, ) { (_, None) => predicate_constraint( </ins> generics, trait_ref.without_const().to_predicate(tcx).to_string(), ), <del> Some((ident, bounds)) => match bounds { [.., bound] => ( bound.span().shrink_to_hi(), format!(" + {}", trait_ref.print_only_trait_path().to_string()), ), [] => ( ident.span.shrink_to_hi(), format!(": {}", trait_ref.print_only_trait_path().to_string()), ), }, </del> <ins> (None, Some((ident, []))) => ( ident.span.shrink_to_hi(), format!(": {}", trait_ref.print_only_trait_path().to_string()), ), (_, Some((_, [.., bounds]))) => ( bounds.span().shrink_to_hi(), format!(" + {}", trait_ref.print_only_trait_path().to_string()), ), (Some(_), Some((_, []))) => ( generics.span.shrink_to_hi(), format!(": {}", trait_ref.print_only_trait_path().to_string()), ), </ins> }; err.span_suggestion_verbose(


//~^ ERROR doesn't implement } <del> pub fn main() { } </del> <ins> trait Foo<T>: Sized { const SIZE: usize = core::mem::size_of::<Self>(); //~^ ERROR the size for values of type `Self` cannot be known at compilation time } trait Bar: std::fmt::Display + Sized { const SIZE: usize = core::mem::size_of::<Self>(); //~^ ERROR the size for values of type `Self` cannot be known at compilation time } trait Baz: Sized where Self: std::fmt::Display { const SIZE: usize = core::mem::size_of::<Self>(); //~^ ERROR the size for values of type `Self` cannot be known at compilation time } trait Qux<T>: Sized where Self: std::fmt::Display { const SIZE: usize = core::mem::size_of::<Self>(); //~^ ERROR the size for values of type `Self` cannot be known at compilation time } trait Bat<T>: std::fmt::Display + Sized { const SIZE: usize = core::mem::size_of::<Self>(); //~^ ERROR the size for values of type `Self` cannot be known at compilation time } fn main() { } </ins>


//~^ ERROR doesn't implement } <del> pub fn main() { } </del> <ins> trait Foo<T> { const SIZE: usize = core::mem::size_of::<Self>(); //~^ ERROR the size for values of type `Self` cannot be known at compilation time } trait Bar: std::fmt::Display { const SIZE: usize = core::mem::size_of::<Self>(); //~^ ERROR the size for values of type `Self` cannot be known at compilation time } trait Baz where Self: std::fmt::Display { const SIZE: usize = core::mem::size_of::<Self>(); //~^ ERROR the size for values of type `Self` cannot be known at compilation time } trait Qux<T> where Self: std::fmt::Display { const SIZE: usize = core::mem::size_of::<Self>(); //~^ ERROR the size for values of type `Self` cannot be known at compilation time } trait Bat<T>: std::fmt::Display { const SIZE: usize = core::mem::size_of::<Self>(); //~^ ERROR the size for values of type `Self` cannot be known at compilation time } fn main() { } </ins>


LL | fn test_many_bounds_where<X>(x: X) where X: Sized, X: Sized, X: Debug { |                                                            ^^^^^^^^^^ <del> error: aborting due to 6 previous errors </del> <ins> error[E0277]: the size for values of type `Self` cannot be known at compilation time --> $DIR/bound-suggestions.rs:44:46 | LL |     const SIZE: usize = core::mem::size_of::<Self>(); |                                              ^^^^ doesn't have a size known at compile-time | ::: $SRC_DIR/core/src/mem/mod.rs:LL:COL | LL | pub const fn size_of<T>() -> usize { |                      - required by this bound in `std::mem::size_of` | help: consider further restricting `Self` | LL | trait Foo<T>: Sized { |             ^^^^^^^ error[E0277]: the size for values of type `Self` cannot be known at compilation time --> $DIR/bound-suggestions.rs:49:46 | LL |     const SIZE: usize = core::mem::size_of::<Self>(); |                                              ^^^^ doesn't have a size known at compile-time | ::: $SRC_DIR/core/src/mem/mod.rs:LL:COL | LL | pub const fn size_of<T>() -> usize { |                      - required by this bound in `std::mem::size_of` | help: consider further restricting `Self` | LL | trait Bar: std::fmt::Display + Sized { |                              ^^^^^^^ error[E0277]: the size for values of type `Self` cannot be known at compilation time --> $DIR/bound-suggestions.rs:54:46 | LL |     const SIZE: usize = core::mem::size_of::<Self>(); |                                              ^^^^ doesn't have a size known at compile-time | ::: $SRC_DIR/core/src/mem/mod.rs:LL:COL | LL | pub const fn size_of<T>() -> usize { |                      - required by this bound in `std::mem::size_of` | help: consider further restricting `Self` | LL | trait Baz: Sized where Self: std::fmt::Display { |          ^^^^^^^ error[E0277]: the size for values of type `Self` cannot be known at compilation time --> $DIR/bound-suggestions.rs:59:46 | LL |     const SIZE: usize = core::mem::size_of::<Self>(); |                                              ^^^^ doesn't have a size known at compile-time | ::: $SRC_DIR/core/src/mem/mod.rs:LL:COL | LL | pub const fn size_of<T>() -> usize { |                      - required by this bound in `std::mem::size_of` | help: consider further restricting `Self` | LL | trait Qux<T>: Sized where Self: std::fmt::Display { |             ^^^^^^^ error[E0277]: the size for values of type `Self` cannot be known at compilation time --> $DIR/bound-suggestions.rs:64:46 | LL |     const SIZE: usize = core::mem::size_of::<Self>(); |                                              ^^^^ doesn't have a size known at compile-time | ::: $SRC_DIR/core/src/mem/mod.rs:LL:COL | LL | pub const fn size_of<T>() -> usize { |                      - required by this bound in `std::mem::size_of` | help: consider further restricting `Self` | LL | trait Bat<T>: std::fmt::Display + Sized { |                                 ^^^^^^^ error: aborting due to 11 previous errors </ins> For more information about this error, try `rustc --explain E0277`.


.iter() .enumerate() .map(|(i, ty)| Argument { <del> name: Symbol::intern(&rustc_hir_pretty::param_to_string(&body.params[i])), </del> <ins> name: name_from_pat(&body.params[i].pat), </ins> type_: ty.clean(cx), }) .collect(),


Path { global: path.global, res: path.res, segments } } <ins> crate fn qpath_to_string(p: &hir::QPath<'_>) -> String { let segments = match *p { hir::QPath::Resolved(_, ref path) => &path.segments, hir::QPath::TypeRelative(_, ref segment) => return segment.ident.to_string(), hir::QPath::LangItem(lang_item, ..) => return lang_item.name().to_string(), }; let mut s = String::new(); for (i, seg) in segments.iter().enumerate() { if i > 0 { s.push_str("::"); } if seg.ident.name != kw::PathRoot { s.push_str(&seg.ident.as_str()); } } s } </ins> crate fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut Vec<Item>) { let tcx = cx.tcx;


} } <ins> crate fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { use rustc_hir::*; debug!("trying to get a name from pattern: {:?}", p); Symbol::intern(&match p.kind { PatKind::Wild => return kw::Underscore, PatKind::Binding(_, _, ident, _) => return ident.name, PatKind::TupleStruct(ref p, ..) | PatKind::Path(ref p) => qpath_to_string(p), PatKind::Struct(ref name, ref fields, etc) => format!( "{} {{ {}{} }}", qpath_to_string(name), fields .iter() .map(|fp| format!("{}: {}", fp.ident, name_from_pat(&fp.pat))) .collect::<Vec<String>>() .join(", "), if etc { ", .." } else { "" } ), PatKind::Or(ref pats) => pats .iter() .map(|p| name_from_pat(&**p).to_string()) .collect::<Vec<String>>() .join(" | "), PatKind::Tuple(ref elts, _) => format!( "({})", elts.iter() .map(|p| name_from_pat(&**p).to_string()) .collect::<Vec<String>>() .join(", ") ), PatKind::Box(ref p) => return name_from_pat(&**p), PatKind::Ref(ref p, _) => return name_from_pat(&**p), PatKind::Lit(..) => { warn!( "tried to get argument name from PatKind::Lit, which is silly in function arguments" ); return Symbol::intern("()"); } PatKind::Range(..) => return kw::Underscore, PatKind::Slice(ref begin, ref mid, ref end) => { let begin = begin.iter().map(|p| name_from_pat(&**p).to_string()); let mid = mid.as_ref().map(|p| format!("..{}", name_from_pat(&**p))).into_iter(); let end = end.iter().map(|p| name_from_pat(&**p).to_string()); format!("[{}]", begin.chain(mid).chain(end).collect::<Vec<_>>().join(", ")) } }) } </ins> crate fn print_const(cx: &DocContext<'_>, n: &'tcx ty::Const<'_>) -> String { match n.val { ty::ConstKind::Unevaluated(def, _, promoted) => {


<ins> // Rustdoc shouldn't display `mut` in function arguments, which are // implementation details. Regression test for #81289. #![crate_name = "foo"] pub struct Foo; // @count foo/struct.Foo.html '//*[@class="impl-items"]//*[@class="method"]' 2 // @!has - '//*[@class="impl-items"]//*[@class="method"]' 'mut' impl Foo { pub fn foo(mut self) {} pub fn bar(mut bar: ()) {} } // @count foo/fn.baz.html '//*[@class="rust fn"]' 1 // @!has - '//*[@class="rust fn"]' 'mut' pub fn baz(mut foo: Foo) {} </ins>


#![crate_name = "foo"] // @has foo/fn.f.html <del> // @has - '//*[@class="rust fn"]' 'pub fn f(0u8 ...255: u8)' </del> <ins> // @has - '//*[@class="rust fn"]' 'pub fn f(_: u8)' </ins> pub fn f(0u8...255: u8) {}


use crate::{lang_items, LangItem, LanguageItems}; use rustc_ast as ast; <del> use rustc_data_structures::fx::FxHashMap; </del> <ins> use rustc_data_structures::stable_map::StableMap; </ins> use rustc_span::symbol::{sym, Symbol}; use std::lazy::SyncLazy;


macro_rules! weak_lang_items { ($($name:ident, $item:ident, $sym:ident;)*) => ( <del> pub static WEAK_ITEMS_REFS: SyncLazy<FxHashMap<Symbol, LangItem>> = SyncLazy::new(|| { let mut map = FxHashMap::default(); </del> <ins> pub static WEAK_ITEMS_REFS: SyncLazy<StableMap<Symbol, LangItem>> = SyncLazy::new(|| { let mut map = StableMap::default(); </ins> $(map.insert(sym::$name, LangItem::$item);)* map });


} } <del> for (name, &item) in WEAK_ITEMS_REFS.iter() { </del> <ins> for (name, item) in WEAK_ITEMS_REFS.clone().into_sorted_vector().into_iter() { </ins> if missing.contains(&item) && required(tcx, item) && items.require(item).is_err() { if item == LangItem::PanicImpl { tcx.sess.err("`#[panic_handler]` function required, but not found");


} } <del> let args = cap.name("args").map_or(vec![], |m| shlex::split(m.as_str()).unwrap()); </del> <ins> let args = cap.name("args").map_or(Some(vec![]), |m| shlex::split(m.as_str())); let args = match args { Some(args) => args, None => { print_err( &format!( "Invalid arguments to shlex::split: `{}`", cap.name("args").unwrap().as_str() ), lineno, ); errors = true; continue; } }; </ins> if !cmd.validate(&args, commands.len(), lineno) { errors = true;


"deref-methods-{:#}", type_.print(cx.cache()) ))); <ins> debug!("Adding {} to deref id map", type_.print(cx.cache())); </ins> cx.deref_id_map .borrow_mut() .insert(type_.def_id_full(cx.cache()).unwrap(), id.clone());


_ => None, }) .expect("Expected associated type binding"); <ins> debug!("Render deref methods for {:#?}, target {:#?}", impl_.inner_impl().for_, target); </ins> let what = AssocItemRender::DerefFor { trait_: deref_type, type_: real_target, deref_mut_: deref_mut }; if let Some(did) = target.def_id_full(cx.cache()) {


}) { debug!("found target, real_target: {:?} {:?}", target, real_target); <ins> if let Some(did) = target.def_id_full(cx.cache()) { if let Some(type_did) = impl_.inner_impl().for_.def_id_full(cx.cache()) { // `impl Deref<Target = S> for S` if did == type_did { // Avoid infinite cycles return; } } } </ins> let deref_mut = v .iter() .filter(|i| i.inner_impl().trait_.is_some())


.filter(|i| i.inner_impl().trait_.is_some()) .find(|i| i.inner_impl().trait_.def_id_full(cx.cache()) == c.deref_trait_did) { <del> if let Some(type_did) = impl_.inner_impl().for_.def_id_full(cx.cache()) { // `impl Deref<Target = S> for S` if target_did == type_did { // Avoid infinite cycles return; } } </del> sidebar_deref_methods(cx, out, target_deref_impl, target_impls); } }


<ins> // check-pass // #81395: Fix ICE when recursing into Deref target only differing in type args pub struct Generic<T>(T); impl<'a> std::ops::Deref for Generic<&'a mut ()> { type Target = Generic<&'a ()>; fn deref(&self) -> &Self::Target { unimplemented!() } } impl<'a> Generic<&'a ()> { pub fn some_method(&self) {} } </ins>


true } }); <del> return INTERNER.intern_path(sysroot); </del> } // Symlink the source root into the same location inside the sysroot,


stable = $stable:expr $(,tool_std = $tool_std:literal)? $(,allow_features = $allow_features:expr)? <ins> $(,add_bins_to_sysroot = $add_bins_to_sysroot:expr)? </ins> ;)+) => { $( #[derive(Debug, Clone, Hash, PartialEq, Eq)]


#[allow(unused_mut)] fn run(mut $sel, $builder: &Builder<'_>) -> Option<PathBuf> { <del> $builder.ensure(ToolBuild { </del> <ins> let tool = $builder.ensure(ToolBuild { </ins> compiler: $sel.compiler, target: $sel.target, tool: $tool_name,


is_optional_tool: true, source_type: SourceType::InTree, allow_features: concat!($($allow_features)*), <del> }) </del> <ins> })?; if (false $(|| !$add_bins_to_sysroot.is_empty())?) && $sel.compiler.stage > 0 { let bindir = $builder.sysroot($sel.compiler).join("bin"); t!(fs::create_dir_all(&bindir)); #[allow(unused_variables)] let tools_out = $builder .cargo_out($sel.compiler, Mode::ToolRustc, $sel.target); $(for add_bin in $add_bins_to_sysroot { let bin_source = tools_out.join(exe(add_bin, $sel.target)); let bin_destination = bindir.join(exe(add_bin, $sel.compiler.host)); $builder.copy(&bin_source, &bin_destination); })? let tool = bindir.join(exe($tool_name, $sel.compiler.host)); Some(tool) } else { Some(tool) } </ins> } } )+


tool_extended!((self, builder), Cargofmt, "src/tools/rustfmt", "cargo-fmt", stable=true; CargoClippy, "src/tools/clippy", "cargo-clippy", stable=true; <del> Clippy, "src/tools/clippy", "clippy-driver", stable=true; Miri, "src/tools/miri", "miri", stable=false; CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=true; </del> <ins> Clippy, "src/tools/clippy", "clippy-driver", stable=true, add_bins_to_sysroot = ["clippy-driver", "cargo-clippy"]; Miri, "src/tools/miri", "miri", stable=false, add_bins_to_sysroot = ["miri"]; CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=true, add_bins_to_sysroot = ["cargo-miri"]; </ins> // FIXME: tool_std is not quite right, we shouldn't allow nightly features. // But `builder.cargo` doesn't know how to handle ToolBootstrap in stages other than 0, // and this is close enough for now. Rls, "src/tools/rls", "rls", stable=true, tool_std=true; RustDemangler, "src/tools/rust-demangler", "rust-demangler", stable=false, tool_std=true; <del> Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true; </del> <ins> Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, add_bins_to_sysroot = ["rustfmt", "cargo-fmt"]; </ins> ); impl<'a> Builder<'a> {


if builder.config.llvm_thin_lto { cfg.define("LLVM_ENABLE_LTO", "Thin"); if !target.contains("apple") { <del> cfg.define("LLVM_USE_LINKER", "lld"); </del> <ins> cfg.define("LLVM_ENABLE_LLD", "ON"); </ins> } }


t!(fs::create_dir_all(&out_dir)); let mut cfg = cmake::Config::new(builder.src.join("src/llvm-project/lld")); <del> if let Some(ref linker) = builder.config.llvm_use_linker { cfg.define("LLVM_USE_LINKER", linker); } </del> configure_cmake(builder, target, &mut cfg, true); // This is an awful, awful hack. Discovered when we migrated to using


--set target.i686-unknown-linux-gnu.linker=clang  --build=i686-unknown-linux-gnu  --set llvm.ninja=false  <del> --set llvm.use-linker=lld  --set rust.use-lld=true  </del> --set rust.jemalloc <del> ENV SCRIPT python3 ../x.py dist --build $HOSTS --host $HOSTS --target $HOSTS </del> <ins> ENV SCRIPT python2.7 ../x.py dist --build $HOSTS --host $HOSTS --target $HOSTS </ins> ENV CARGO_TARGET_I686_UNKNOWN_LINUX_GNU_LINKER=clang # This was added when we switched from gcc to clang. It's not clear why this is


COPY host-x86_64/dist-x86_64-linux/build-gcc.sh /tmp/ RUN ./build-gcc.sh && apt-get remove -y gcc g++ <del> # Debian 6 has Python 2.6 by default, but LLVM >= 12 needs Python 3 </del> <ins> # Debian 6 has Python 2.6 by default, but LLVM needs 2.7+ </ins> COPY host-x86_64/dist-x86_64-linux/build-python.sh /tmp/ RUN ./build-python.sh <del> # LLVM needs cmake 3.13.4 or higher </del> <ins> # LLVM needs cmake 3.4.3 or higher, and is planning to raise to 3.13.4. </ins> COPY host-x86_64/dist-x86_64-linux/build-cmake.sh /tmp/ RUN ./build-cmake.sh


--set target.x86_64-unknown-linux-gnu.ranlib=/rustroot/bin/llvm-ranlib  --set llvm.thin-lto=true  --set llvm.ninja=false  <del> --set llvm.use-linker=lld  --set rust.use-lld=true  </del> --set rust.jemalloc <del> ENV SCRIPT ../src/ci/pgo.sh python3 ../x.py dist  </del> <ins> ENV SCRIPT ../src/ci/pgo.sh python2.7 ../x.py dist  </ins> --host $HOSTS --target $HOSTS  --include-default-paths  src/tools/build-manifest


source shared.sh <del> LLVM=llvmorg-11.0.1 </del> <ins> LLVM=llvmorg-10.0.0 </ins> mkdir llvm-project cd llvm-project


set -ex source shared.sh <del> curl https://www.python.org/ftp/python/3.9.1/Python-3.9.1.tgz |  </del> <ins> curl https://www.python.org/ftp/python/2.7.12/Python-2.7.12.tgz |  </ins> tar xzf - mkdir python-build


# Gotta do some hackery to tell python about our custom OpenSSL build, but other # than that fairly normal. CFLAGS='-I /rustroot/include' LDFLAGS='-L /rustroot/lib -L /rustroot/lib64'  <del> hide_output ../Python-3.9.1/configure --prefix=/rustroot </del> <ins> hide_output ../Python-2.7.12/configure --prefix=/rustroot </ins> hide_output make -j10 hide_output make install cd .. rm -rf python-build <del> rm -rf Python-3.9.1 </del> <ins> rm -rf Python-2.7.12 </ins>


rm -rf /tmp/rustc-pgo <del> python3 ../x.py build --target=$PGO_HOST --host=$PGO_HOST  </del> <ins> python2.7 ../x.py build --target=$PGO_HOST --host=$PGO_HOST  </ins> --stage 2 library/std --rust-profile-generate=/tmp/rustc-pgo ./build/$PGO_HOST/stage2/bin/rustc --edition=2018


LookupResult::Parent(Some(parent)) => { let (_maybe_live, maybe_dead) = self.init_data.maybe_live_dead(parent); if maybe_dead { <del> span_bug!( </del> <ins> self.tcx.sess.delay_span_bug( </ins> terminator.source_info.span, <del> "drop of untracked, uninitialized value {:?}, place {:?} ({:?})", bb, place, path </del> <ins> &format!( "drop of untracked, uninitialized value {:?}, place {:?} ({:?})", bb, place, path, ), </ins> ); } continue;


bb, ), LookupResult::Parent(..) => { <del> span_bug!( </del> <ins> self.tcx.sess.delay_span_bug( </ins> terminator.source_info.span, <del> "drop of untracked value {:?}", bb </del> <ins> &format!("drop of untracked value {:?}", bb), </ins> ); } }


<ins> // Regression test for issue 81708 and issue 91816 where running a drop // elaboration on a MIR which failed borrowck lead to an ICE. static A: () = { let a: [String; 1]; //~^ ERROR destructors cannot be evaluated at compile-time a[0] = String::new(); //~^ ERROR destructors cannot be evaluated at compile-time //~| ERROR use of possibly-uninitialized variable }; struct B<T>([T; 1]); impl<T> B<T> { pub const fn f(mut self, other: T) -> Self { let _this = self; //~^ ERROR destructors cannot be evaluated at compile-time self.0[0] = other; //~^ ERROR destructors cannot be evaluated at compile-time //~| ERROR use of moved value self } } fn main() {} </ins>


<ins> error[E0493]: destructors cannot be evaluated at compile-time --> $DIR/drop-elaboration-after-borrowck-error.rs:7:5 | LL |     a[0] = String::new(); |     ^^^^ |     | |     statics cannot evaluate destructors |     value is dropped here error[E0493]: destructors cannot be evaluated at compile-time --> $DIR/drop-elaboration-after-borrowck-error.rs:5:9 | LL |     let a: [String; 1]; |         ^ statics cannot evaluate destructors ... LL | }; | - value is dropped here error[E0381]: use of possibly-uninitialized variable: `a` --> $DIR/drop-elaboration-after-borrowck-error.rs:7:5 | LL |     a[0] = String::new(); |     ^^^^ use of possibly-uninitialized `a` error[E0493]: destructors cannot be evaluated at compile-time --> $DIR/drop-elaboration-after-borrowck-error.rs:18:9 | LL |         self.0[0] = other; |         ^^^^^^^^^ |         | |         constant functions cannot evaluate destructors |         value is dropped here error[E0493]: destructors cannot be evaluated at compile-time --> $DIR/drop-elaboration-after-borrowck-error.rs:16:13 | LL |         let _this = self; |             ^^^^^ constant functions cannot evaluate destructors ... LL |     } |     - value is dropped here error[E0382]: use of moved value: `self.0` --> $DIR/drop-elaboration-after-borrowck-error.rs:18:9 | LL |     pub const fn f(mut self, other: T) -> Self { |                    -------- move occurs because `self` has type `B<T>`, which does not implement the `Copy` trait LL |         let _this = self; |                     ---- value moved here LL | LL |         self.0[0] = other; |         ^^^^^^^^^ value used here after move error: aborting due to 6 previous errors Some errors have detailed explanations: E0381, E0382, E0493. For more information about an error, try `rustc --explain E0381`. </ins>


<ins> // Regression test for #81712. #![feature(generic_associated_types)] #![allow(incomplete_features)] trait A { type BType: B<AType = Self>; } trait B { type AType: A<BType = Self>; } trait C { type DType<T>: D<T, CType = Self>; //~^ ERROR: missing generics for associated type `C::DType` [E0107] } trait D<T> { type CType: C<DType = Self>; } fn main() {} </ins>


<ins> error[E0107]: missing generics for associated type `C::DType` --> $DIR/issue-81712-cyclic-traits.rs:14:10 | LL |     type DType<T>: D<T, CType = Self>; |          ^^^^^ expected 1 type argument | note: associated type defined here, with 1 type parameter: `T` --> $DIR/issue-81712-cyclic-traits.rs:14:10 | LL |     type DType<T>: D<T, CType = Self>; |          ^^^^^ - help: use angle brackets to add missing type argument | LL |     type DType<T><T>: D<T, CType = Self>; |               ^^^ error: aborting due to previous error For more information about this error, try `rustc --explain E0107`. </ins>


<ins> // error-pattern: this file contains an unclosed delimiter // error-pattern: mismatched closing delimiter: `]` // error-pattern: expected one of `)` or `,`, found `{` #![crate_name="0"] fn main() {} fn r()->i{0|{#[cfg(r(0{]0 </ins>


<ins> error: this file contains an unclosed delimiter --> $DIR/issue-81827.rs:11:27 | LL | fn r()->i{0|{#[cfg(r(0{]0 |          -  -             ^ |          |  | |          |  unclosed delimiter |          unclosed delimiter error: this file contains an unclosed delimiter --> $DIR/issue-81827.rs:11:27 | LL | fn r()->i{0|{#[cfg(r(0{]0 |          -  -             ^ |          |  | |          |  unclosed delimiter |          unclosed delimiter error: mismatched closing delimiter: `]` --> $DIR/issue-81827.rs:11:23 | LL | fn r()->i{0|{#[cfg(r(0{]0 |               -       ^^ mismatched closing delimiter |               |       | |               |       unclosed delimiter |               closing delimiter possibly meant for this error: expected one of `)` or `,`, found `{` --> $DIR/issue-81827.rs:11:23 | LL | fn r()->i{0|{#[cfg(r(0{]0 |                       ^ expected one of `)` or `,` error: aborting due to 4 previous errors </ins>


}; let last_expr_ty = self.node_ty(last_expr.hir_id); let needs_box = match (last_expr_ty.kind(), expected_ty.kind()) { <ins> (ty::Opaque(last_def_id, _), ty::Opaque(exp_def_id, _)) if last_def_id == exp_def_id => { StatementAsExpression::CorrectType } </ins> (ty::Opaque(last_def_id, last_bounds), ty::Opaque(exp_def_id, exp_bounds)) => { debug!( "both opaque, likely future {:?} {:?} {:?} {:?}", last_def_id, last_bounds, exp_def_id, exp_bounds ); <del> let last_hir_id = self.tcx.hir().local_def_id_to_hir_id(last_def_id.expect_local()); let exp_hir_id = self.tcx.hir().local_def_id_to_hir_id(exp_def_id.expect_local()); </del> <ins> let (last_local_id, exp_local_id) = match (last_def_id.as_local(), exp_def_id.as_local()) { (Some(last_hir_id), Some(exp_hir_id)) => (last_hir_id, exp_hir_id), (_, _) => return None, }; let last_hir_id = self.tcx.hir().local_def_id_to_hir_id(last_local_id); let exp_hir_id = self.tcx.hir().local_def_id_to_hir_id(exp_local_id); </ins> match ( &self.tcx.hir().expect_item(last_hir_id).kind, &self.tcx.hir().expect_item(exp_hir_id).kind,


<ins> // edition:2018 pub struct Test {} impl Test { pub async fn answer_str(&self, _s: &str) -> Test { Test {} } } </ins>


<ins> // aux-build:issue-81839.rs // edition:2018 extern crate issue_81839; async fn test(ans: &str, num: i32, cx: &issue_81839::Test) -> u32 { match num { 1 => { cx.answer_str("hi"); } _ => cx.answer_str("hi"), //~ `match` arms have incompatible types } 1 } fn main() {} </ins>


<ins> error[E0308]: `match` arms have incompatible types --> $DIR/issue-81839.rs:11:14 | LL | /     match num { LL | |         1 => { LL | |             cx.answer_str("hi"); | |             -------------------- | |             |                  | | |             |                  help: consider removing this semicolon | |             this is found to be of type `()` LL | |         } LL | |         _ => cx.answer_str("hi"), | |              ^^^^^^^^^^^^^^^^^^^ expected `()`, found opaque type LL | |     } | |_____- `match` arms have incompatible types | ::: $DIR/auxiliary/issue-81839.rs:6:49 | LL |       pub async fn answer_str(&self, _s: &str) -> Test { |                                                   ---- the `Output` of this `async fn`'s found opaque type | = note:     expected type `()` found opaque type `impl Future` error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. </ins>


| LL |         false => async_dummy().await, |                               ^^^^^^ <del> help: consider removing this semicolon and boxing the expressions | LL |             Box::new(async_dummy()) LL | LL |         } LL |         false => Box::new(async_dummy()), </del> <ins> help: consider removing this semicolon </ins> | <ins> LL |             async_dummy() |                         -- </ins> error[E0308]: `match` arms have incompatible types --> $DIR/match-prev-arm-needing-semi.rs:39:18


struct_span_err!(tcx.sess, span, E0733, "recursion in an `async fn` requires boxing") .span_label(span, "recursive `async fn`") .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`") <ins> .note( "consider using the `async_recursion` crate: https://crates.io/crates/async_recursion", ) </ins> .emit(); }


|                  ^ recursive `async fn` | = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future` <ins> = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion </ins> error[E0733]: recursion in an `async fn` requires boxing --> $DIR/mutually-recursive-async-impl-trait-type.rs:9:18


|                  ^ recursive `async fn` | = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future` <ins> = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion </ins> error: aborting due to 2 previous errors


|                                        ^^ recursive `async fn` | = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future` <ins> = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion </ins> error: aborting due to previous error


} impl Attribute { <ins> #[inline] </ins> pub fn has_name(&self, name: Symbol) -> bool { match self.kind { AttrKind::Normal(ref item, _) => item.path == name,


use rustc_middle::ty::query::Providers; use rustc_middle::ty::TyCtxt; <del> use rustc_ast::{Attribute, LitKind, NestedMetaItem}; </del> <ins> use rustc_ast::{Attribute, Lit, LitKind, NestedMetaItem}; </ins> use rustc_errors::{pluralize, struct_span_err}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId;


self.check_export_name(hir_id, &attr, span, target) } else if self.tcx.sess.check_name(attr, sym::rustc_args_required_const) { self.check_rustc_args_required_const(&attr, span, target, item) <ins> } else if self.tcx.sess.check_name(attr, sym::rustc_layout_scalar_valid_range_start) { self.check_rustc_layout_scalar_valid_range(&attr, span, target) } else if self.tcx.sess.check_name(attr, sym::rustc_layout_scalar_valid_range_end) { self.check_rustc_layout_scalar_valid_range(&attr, span, target) </ins> } else if self.tcx.sess.check_name(attr, sym::allow_internal_unstable) { self.check_allow_internal_unstable(hir_id, &attr, span, target, &attrs) } else if self.tcx.sess.check_name(attr, sym::rustc_allow_const_fn_unstable) {


} } <ins> fn check_rustc_layout_scalar_valid_range( &self, attr: &Attribute, span: &Span, target: Target, ) -> bool { if target != Target::Struct { self.tcx .sess .struct_span_err(attr.span, "attribute should be applied to a struct") .span_label(*span, "not a struct") .emit(); return false; } let list = match attr.meta_item_list() { None => return false, Some(it) => it, }; if matches!(&list[..], &[NestedMetaItem::Literal(Lit { kind: LitKind::Int(..), .. })]) { true } else { self.tcx .sess .struct_span_err(attr.span, "expected exactly one integer literal argument") .emit(); false } } </ins> /// Checks if `#[rustc_legacy_const_generics]` is applied to a function and has a valid argument. fn check_rustc_legacy_const_generics( &self,


<ins> #![feature(rustc_attrs)] #[rustc_layout_scalar_valid_range_start(u32::MAX)] //~ ERROR pub struct A(u32); #[rustc_layout_scalar_valid_range_end(1, 2)] //~ ERROR pub struct B(u8); #[rustc_layout_scalar_valid_range_end(a = "a")] //~ ERROR pub struct C(i32); #[rustc_layout_scalar_valid_range_end(1)] //~ ERROR enum E { X = 1, Y = 14, } fn main() { let _ = A(0); let _ = B(0); let _ = C(0); let _ = E::X; } </ins>


<ins> error: expected exactly one integer literal argument --> $DIR/invalid_rustc_layout_scalar_valid_range.rs:3:1 | LL | #[rustc_layout_scalar_valid_range_start(u32::MAX)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: expected exactly one integer literal argument --> $DIR/invalid_rustc_layout_scalar_valid_range.rs:6:1 | LL | #[rustc_layout_scalar_valid_range_end(1, 2)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: expected exactly one integer literal argument --> $DIR/invalid_rustc_layout_scalar_valid_range.rs:9:1 | LL | #[rustc_layout_scalar_valid_range_end(a = "a")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: attribute should be applied to a struct --> $DIR/invalid_rustc_layout_scalar_valid_range.rs:12:1 | LL |   #[rustc_layout_scalar_valid_range_end(1)] |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | / enum E { LL | |     X = 1, LL | |     Y = 14, LL | | } | |_- not a struct error: aborting due to 4 previous errors </ins>


pub struct Zip<A, B> { a: A, b: B, <del> // index and len are only used by the specialized version of zip </del> <ins> // index, len and a_len are only used by the specialized version of zip </ins> index: usize, len: usize, <ins> a_len: usize, </ins> } impl<A: Iterator, B: Iterator> Zip<A, B> { pub(in crate::iter) fn new(a: A, b: B) -> Zip<A, B> {


b, index: 0, // unused len: 0,   // unused <ins> a_len: 0, // unused </ins> } }


B: TrustedRandomAccess + Iterator, { fn new(a: A, b: B) -> Self { <del> let len = cmp::min(a.size(), b.size()); Zip { a, b, index: 0, len } </del> <ins> let a_len = a.size(); let len = cmp::min(a_len, b.size()); Zip { a, b, index: 0, len, a_len } </ins> } #[inline]


unsafe { Some((self.a.__iterator_get_unchecked(i), self.b.__iterator_get_unchecked(i))) } <del> } else if A::MAY_HAVE_SIDE_EFFECT && self.index < self.a.size() { </del> <ins> } else if A::MAY_HAVE_SIDE_EFFECT && self.index < self.a_len { </ins> let i = self.index; self.index += 1; self.len += 1;


for _ in 0..sz_a - self.len { self.a.next_back(); } <ins> self.a_len = self.len; </ins> } let sz_b = self.b.size(); if B::MAY_HAVE_SIDE_EFFECT && sz_b > self.len {


} if self.index < self.len { self.len -= 1; <ins> self.a_len -= 1; </ins> let i = self.len; // SAFETY: `i` is smaller than the previous value of `self.len`, // which is also smaller than or equal to `self.a.len()` and `self.b.len()`


panic!(); } } <ins> #[test] fn test_issue_82291() { use std::cell::Cell; let mut v1 = [()]; let v2 = [()]; let called = Cell::new(0); let mut zip = v1 .iter_mut() .map(|r| { called.set(called.get() + 1); r }) .zip(&v2); zip.next_back(); assert_eq!(called.get(), 1); zip.next(); assert_eq!(called.get(), 1); } </ins>


expr } <ins> pub fn peel_blocks(&self) -> &Self { let mut expr = self; while let ExprKind::Block(Block { expr: Some(inner), .. }, _) = &expr.kind { expr = inner; } expr } </ins> pub fn can_have_side_effects(&self) -> bool { match self.peel_drop_temps().kind { ExprKind::Path(_) | ExprKind::Lit(_) => false,


} _ if sp == expr.span && !is_macro => { if let Some(steps) = self.deref_steps(checked_ty, expected) { <ins> let expr = expr.peel_blocks(); </ins> if steps == 1 { <del> // For a suggestion to make sense, the type would need to be `Copy`. if self.infcx.type_is_copy_modulo_regions(self.param_env, expected, sp) { if let Ok(code) = sm.span_to_snippet(sp) { </del> <ins> if let hir::ExprKind::AddrOf(_, mutbl, inner) = expr.kind { // If the expression has `&`, removing it would fix the error let prefix_span = expr.span.with_hi(inner.span.lo()); let message = match mutbl { hir::Mutability::Not => "consider removing the `&`", hir::Mutability::Mut => "consider removing the `&mut`", }; let suggestion = String::new(); return Some(( prefix_span, message, suggestion, Applicability::MachineApplicable, )); } else if self.infcx.type_is_copy_modulo_regions( self.param_env, expected, sp, ) { // For this suggestion to make sense, the type would need to be `Copy`. if let Ok(code) = sm.span_to_snippet(expr.span) { </ins> let message = if checked_ty.is_region_ptr() { "consider dereferencing the borrow" } else {


format!("*{}", code) }; return Some(( <del> sp, </del> <ins> expr.span, </ins> message, suggestion, Applicability::MachineApplicable,


<ins> // run-rustfix fn main() { let a: usize = 123; let b: &usize = &a; if true { a } else { *b //~ ERROR `if` and `else` have incompatible types [E0308] }; if true { 1 } else { 1 //~ ERROR `if` and `else` have incompatible types [E0308] }; if true { 1 } else { 1 //~ ERROR `if` and `else` have incompatible types [E0308] }; } </ins>


<ins> // run-rustfix fn main() { let a: usize = 123; let b: &usize = &a; if true { a } else { b //~ ERROR `if` and `else` have incompatible types [E0308] }; if true { 1 } else { &1 //~ ERROR `if` and `else` have incompatible types [E0308] }; if true { 1 } else { &mut 1 //~ ERROR `if` and `else` have incompatible types [E0308] }; } </ins>


<ins> error[E0308]: `if` and `else` have incompatible types --> $DIR/issue-82361.rs:10:9 | LL | /     if true { LL | |         a | |         - expected because of this LL | |     } else { LL | |         b | |         ^ | |         | | |         expected `usize`, found `&usize` | |         help: consider dereferencing the borrow: `*b` LL | |     }; | |_____- `if` and `else` have incompatible types error[E0308]: `if` and `else` have incompatible types --> $DIR/issue-82361.rs:16:9 | LL | /     if true { LL | |         1 | |         - expected because of this LL | |     } else { LL | |         &1 | |         -^ | |         | | |         expected integer, found `&{integer}` | |         help: consider removing the `&` LL | |     }; | |_____- `if` and `else` have incompatible types error[E0308]: `if` and `else` have incompatible types --> $DIR/issue-82361.rs:22:9 | LL | /     if true { LL | |         1 | |         - expected because of this LL | |     } else { LL | |         &mut 1 | |         -----^ | |         | | |         expected integer, found `&mut {integer}` | |         help: consider removing the `&mut` LL | |     }; | |_____- `if` and `else` have incompatible types error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0308`. </ins>


name = "compiletest" version = "0.0.0" dependencies = [ <ins> "colored", </ins> "diff", "getopts", "glob",


"serde_json", "tracing", "tracing-subscriber", <ins> "unified-diff", </ins> "walkdir", "winapi 0.3.9", ]


checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" [[package]] <ins> name = "unified-diff" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "496a3d395ed0c30f411ceace4a91f7d93b148fb5a9b383d5d4cff7850f048d5f" dependencies = [ "diff", ] [[package]] </ins> name = "unstable-book-gen" version = "0.1.0" dependencies = [


edition = "2018" [dependencies] <ins> colored = "2" </ins> diff = "0.1.10" <ins> unified-diff = "0.2.1" </ins> getopts = "0.2" tracing = "0.1" tracing-subscriber = { version = "0.2.13", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] }


use crate::json; use crate::util::get_pointer_width; use crate::util::{logv, PathBufExt}; <ins> use crate::ColorConfig; </ins> use regex::{Captures, Regex}; use rustfix::{apply_suggestions, get_suggestions_from_json, Filter};


} }) }; <del> let mut diff = Command::new("diff"); // diff recursively, showing context, and excluding .css files diff.args(&["-u", "-r", "-x", "*.css"]).args(&[&compare_dir, out_dir]); let output = if let Some(pager) = pager { let diff_pid = diff.stdout(Stdio::piped()).spawn().expect("failed to run `diff`"); </del> <ins> let diff_filename = format!("build/tmp/rustdoc-compare-{}.diff", std::process::id()); { let mut diff_output = File::create(&diff_filename).unwrap(); for entry in walkdir::WalkDir::new(out_dir) { let entry = entry.expect("failed to read file"); let extension = entry.path().extension().and_then(|p| p.to_str()); if entry.file_type().is_file() && (extension == Some("html".into()) || extension == Some("js".into())) { let expected_path = compare_dir.join(entry.path().strip_prefix(&out_dir).unwrap()); let expected = if let Ok(s) = std::fs::read(&expected_path) { s } else { continue }; let actual_path = entry.path(); let actual = std::fs::read(&actual_path).unwrap(); diff_output .write_all(&unified_diff::diff( &expected, &expected_path.to_string_lossy(), &actual, &actual_path.to_string_lossy(), 3, )) .unwrap(); } } } match self.config.color { ColorConfig::AlwaysColor => colored::control::set_override(true), ColorConfig::NeverColor => colored::control::set_override(false), _ => {} } if let Some(pager) = pager { </ins> let pager = pager.trim(); if self.config.verbose { eprintln!("using pager {}", pager);


let output = Command::new(pager) // disable paging; we want this to be non-interactive .env("PAGER", "") <del> .stdin(diff_pid.stdout.unwrap()) </del> <ins> .stdin(File::open(&diff_filename).unwrap()) </ins> // Capture output and print it explicitly so it will in turn be // captured by libtest. .output() .unwrap(); assert!(output.status.success()); <del> output </del> <ins> println!("{}", String::from_utf8_lossy(&output.stdout)); eprintln!("{}", String::from_utf8_lossy(&output.stderr)); </ins> } else { <del> eprintln!("warning: no pager configured, falling back to `diff --color`"); </del> <ins> use colored::Colorize; eprintln!("warning: no pager configured, falling back to unified diff"); </ins> eprintln!( "help: try configuring a git pager (e.g. `delta`) with `git config --global core.pager delta`" ); <del> let output = diff.arg("--color").output().unwrap(); assert!(output.status.success() || output.status.code() == Some(1)); output </del> <ins> let mut out = io::stdout(); let mut diff = BufReader::new(File::open(&diff_filename).unwrap()); let mut line = Vec::new(); loop { line.truncate(0); match diff.read_until(b'n', &mut line) { Ok(0) => break, Ok(_) => {} Err(e) => eprintln!("ERROR: {:?}", e), } match String::from_utf8(line.clone()) { Ok(line) => { if line.starts_with("+") { write!(&mut out, "{}", line.green()).unwrap(); } else if line.starts_with("-") { write!(&mut out, "{}", line.red()).unwrap(); } else if line.starts_with("@") { write!(&mut out, "{}", line.blue()).unwrap(); } else { out.write_all(line.as_bytes()).unwrap(); } } Err(_) => { write!(&mut out, "{}", String::from_utf8_lossy(&line).reversed()).unwrap(); } } } </ins> }; <del> println!("{}", String::from_utf8_lossy(&output.stdout)); eprintln!("{}", String::from_utf8_lossy(&output.stderr)); </del> } fn run_rustdoc_json_test(&self) {


let id = id.expect_local(); let tables = tcx.typeck(id); let hir_id = tcx.hir().local_def_id_to_hir_id(id); <del> let (span, place) = &tables.closure_kind_origins()[hir_id]; let reason = if let PlaceBase::Upvar(upvar_id) = place.base { let upvar = ty::place_to_string_for_capture(tcx, place); match tables.upvar_capture(upvar_id) { ty::UpvarCapture::ByRef(ty::UpvarBorrow { kind: ty::BorrowKind::MutBorrow | ty::BorrowKind::UniqueImmBorrow, .. }) => { format!("mutable borrow of `{}`", upvar) } ty::UpvarCapture::ByValue(_) => { format!("possible mutation of `{}`", upvar) </del> <ins> if let Some((span, place)) = tables.closure_kind_origins().get(hir_id) { let reason = if let PlaceBase::Upvar(upvar_id) = place.base { let upvar = ty::place_to_string_for_capture(tcx, place); match tables.upvar_capture(upvar_id) { ty::UpvarCapture::ByRef(ty::UpvarBorrow { kind: ty::BorrowKind::MutBorrow | ty::BorrowKind::UniqueImmBorrow, .. }) => { format!("mutable borrow of `{}`", upvar) } ty::UpvarCapture::ByValue(_) => { format!("possible mutation of `{}`", upvar) } val => bug!("upvar `{}` borrowed, but not mutably: {:?}", upvar, val), </ins> } <del> val => bug!("upvar `{}` borrowed, but not mutably: {:?}", upvar, val), } } else { bug!("not an upvar") }; err.span_label( *span, format!( "calling `{}` requires mutable binding due to {}", self.describe_place(the_place_err).unwrap(), reason ), ); </del> <ins> } else { bug!("not an upvar") }; err.span_label( *span, format!( "calling `{}` requires mutable binding due to {}", self.describe_place(the_place_err).unwrap(), reason ), ); } </ins> } // Attempt to search similar mutable associated items for suggestion.


<ins> use std::error::Error; struct A { } impl A { pub fn new() -> A { A { } } pub fn f<'a>( &'a self, team_name: &'a str, c: &'a mut dyn FnMut(String, String, u64, u64) ) -> Result<(), Box<dyn Error>> { Ok(()) } } fn main() { let A = A::new(); let participant_name = "A"; let c = |a, b, c, d| {}; A.f(participant_name, &mut c); //~ ERROR cannot borrow } </ins>


<ins> error[E0596]: cannot borrow `c` as mutable, as it is not declared as mutable --> $DIR/issue-82438-mut-without-upvar.rs:27:27 | LL |     let c = |a, b, c, d| {}; |         - help: consider changing this to be mutable: `mut c` LL | LL |     A.f(participant_name, &mut c); |                           ^^^^^^ cannot borrow as mutable error: aborting due to previous error For more information about this error, try `rustc --explain E0596`. </ins>


span: Span, ) -> &'tcx Const<'tcx> { bad_placeholder_type(self.tcx(), vec![span]).emit(); <ins> // Typeck doesn't expect erased regions to be returned from `type_of`. let ty = self.tcx.fold_regions(ty, &mut false, |r, _| match r { ty::ReErased => self.tcx.lifetimes.re_static, _ => r, }); </ins> self.tcx().const_error(ty) }


match get_infer_ret_ty(&sig.decl.output) { Some(ty) => { let fn_sig = tcx.typeck(def_id).liberated_fn_sigs()[hir_id]; <ins> // Typeck doesn't expect erased regions to be returned from `type_of`. let fn_sig = tcx.fold_regions(fn_sig, &mut false, |r, _| match r { ty::ReErased => tcx.lifetimes.re_static, _ => r, }); </ins> let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_ty(ty); let mut diag = bad_placeholder_type(tcx, visitor.0);


} } diag.emit(); ty::Binder::bind(fn_sig) } None => AstConv::ty_of_fn(


const D: _ = 42; //~^ ERROR the type placeholder `_` is not allowed within types on item signatures } <ins> fn map<T>(_: fn() -> Option<&'static T>) -> Option<T> { None } fn value() -> Option<&'static _> { //~^ ERROR the type placeholder `_` is not allowed within types on item signatures Option::<&'static u8>::None } const _: Option<_> = map(value); //~^ ERROR the type placeholder `_` is not allowed within types on item signatures </ins>


|                         -^ |                         || |                         |not allowed in type signatures <del> |                         help: replace with the correct return type: `&&usize` </del> <ins> |                         help: replace with the correct return type: `&'static &'static usize` </ins> error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:52:52


|                     ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures <ins> --> $DIR/typeck_type_placeholder_item.rs:216:31 | LL | fn value() -> Option<&'static _> { |               ----------------^- |               |               | |               |               not allowed in type signatures |               help: replace with the correct return type: `Option<&'static u8>` error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:221:10 | LL | const _: Option<_> = map(value); |          ^^^^^^^^^ |          | |          not allowed in type signatures |          help: replace `_` with the correct type: `Option<u8>` error[E0121]: the type placeholder `_` is not allowed within types on item signatures </ins> --> $DIR/typeck_type_placeholder_item.rs:140:31 | LL |     fn method_test1(&self, x: _);


|              not allowed in type signatures |              help: replace `_` with the correct type: `i32` <del> error: aborting due to 67 previous errors </del> <ins> error: aborting due to 69 previous errors </ins> Some errors have detailed explanations: E0121, E0282, E0403. For more information about an error, try `rustc --explain E0121`.


/// destination value, then forgets the original. It's equivalent to C's /// `memcpy` under the hood, just like `transmute_copy`. /// <ins> /// Because `transmute` is a by-value operation, alignment of the *transmuted values /// themselves* is not a concern. As with any other function, the compiler already ensures /// both `T` and `U` are properly aligned. However, when transmuting values that *point /// elsewhere* (such as pointers, references, boxes…), the caller has to ensure proper /// alignment of the pointed-to values. /// </ins> /// `transmute` is **incredibly** unsafe. There are a vast number of ways to /// cause [undefined behavior][ub] with this function. `transmute` should be /// the absolute last resort.


/// assert_eq!(b"Rust", &[82, 117, 115, 116]); /// ``` /// <del> /// Turning a `Vec<&T>` into a `Vec<Option<&T>>`: </del> <ins> /// Turning a `Vec<&T>` into a `Vec<Option<&T>>`. /// /// To transmute the inner type of the contents of a container, you must make sure to not /// violate any of the container's invariants. For `Vec`, this means that both the size /// *and alignment* of the inner types have to match. Other containers might rely on the /// size of the type, alignment, or even the `TypeId`, in which case transmuting wouldn't /// be possible at all without violating the container invariants. </ins> /// /// ``` /// let store = [0, 1, 2, 3];


/// /// let v_clone = v_orig.clone(); /// <del> /// // The no-copy, unsafe way, still using transmute, but not relying on the data layout. /// // Like the first approach, this reuses the `Vec` internals. /// // Therefore, the new inner type must have the /// // exact same size, *and the same alignment*, as the old type. /// // The same caveats exist for this method as transmute, for /// // the original inner type (`&i32`) to the converted inner type /// // (`Option<&i32>`), so read the nomicon pages linked above and also /// // consult the [`from_raw_parts`] documentation. </del> <ins> /// // This is the proper no-copy, unsafe way of "transmuting" a `Vec`, without relying on the /// // data layout. Instead of literally calling `transmute`, we perform a pointer cast, but /// // in terms of converting the original inner type (`&i32`) to the new one (`Option<&i32>`), /// // this has all the same caveats. Besides the information provided above, also consult the /// // [`from_raw_parts`] documentation. </ins> /// let v_from_raw = unsafe { // FIXME Update this when vec_into_raw_parts is stabilized ///     // Ensure the original vector is not dropped.


<ins> // run-rustfix #![allow(dead_code, unused_variables)] fn foo1(bar: &str) {} //~^ ERROR the size for values of type `str` cannot be known at compilation time //~| HELP the trait `Sized` is not implemented for `str` //~| HELP unsized fn params are gated as an unstable feature //~| HELP function arguments must have a statically known size, borrowed types always have a known size fn foo2(_bar: &str) {} //~^ ERROR the size for values of type `str` cannot be known at compilation time //~| HELP the trait `Sized` is not implemented for `str` //~| HELP unsized fn params are gated as an unstable feature //~| HELP function arguments must have a statically known size, borrowed types always have a known size fn foo3(_: &str) {} //~^ ERROR the size for values of type `str` cannot be known at compilation time //~| HELP the trait `Sized` is not implemented for `str` //~| HELP unsized fn params are gated as an unstable feature //~| HELP function arguments must have a statically known size, borrowed types always have a known size fn main() {} </ins>


<ins> // run-rustfix #![allow(dead_code, unused_variables)] fn foo1(bar: str) {} //~^ ERROR the size for values of type `str` cannot be known at compilation time //~| HELP the trait `Sized` is not implemented for `str` //~| HELP unsized fn params are gated as an unstable feature //~| HELP function arguments must have a statically known size, borrowed types always have a known size fn foo2(_bar: str) {} //~^ ERROR the size for values of type `str` cannot be known at compilation time //~| HELP the trait `Sized` is not implemented for `str` //~| HELP unsized fn params are gated as an unstable feature //~| HELP function arguments must have a statically known size, borrowed types always have a known size fn foo3(_: str) {} //~^ ERROR the size for values of type `str` cannot be known at compilation time //~| HELP the trait `Sized` is not implemented for `str` //~| HELP unsized fn params are gated as an unstable feature //~| HELP function arguments must have a statically known size, borrowed types always have a known size fn main() {} </ins>


<ins> error[E0277]: the size for values of type `str` cannot be known at compilation time --> $DIR/unsized-function-parameter.rs:5:9 | LL | fn foo1(bar: str) {} |         ^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` = help: unsized fn params are gated as an unstable feature help: function arguments must have a statically known size, borrowed types always have a known size | LL | fn foo1(bar: &str) {} |              ^ error[E0277]: the size for values of type `str` cannot be known at compilation time --> $DIR/unsized-function-parameter.rs:11:9 | LL | fn foo2(_bar: str) {} |         ^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` = help: unsized fn params are gated as an unstable feature help: function arguments must have a statically known size, borrowed types always have a known size | LL | fn foo2(_bar: &str) {} |               ^ error[E0277]: the size for values of type `str` cannot be known at compilation time --> $DIR/unsized-function-parameter.rs:17:9 | LL | fn foo3(_: str) {} |         ^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` = help: unsized fn params are gated as an unstable feature help: function arguments must have a statically known size, borrowed types always have a known size | LL | fn foo3(_: &str) {} |            ^ error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. </ins>


let dl = self.data_layout(); let pack = repr.pack; if pack.is_some() && repr.align.is_some() { <del> bug!("struct cannot be packed and aligned"); </del> <ins> self.tcx.sess.delay_span_bug(DUMMY_SP, "struct cannot be packed and aligned"); return Err(LayoutError::Unknown(ty)); </ins> } let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align };


if def.is_union() { if def.repr.pack.is_some() && def.repr.align.is_some() { <del> bug!("union cannot be packed and aligned"); </del> <ins> self.tcx.sess.delay_span_bug( tcx.def_span(def.did), "union cannot be packed and aligned", ); return Err(LayoutError::Unknown(ty)); </ins> } let mut align =


i: i32, } <ins> #[repr(packed, align(0x100))] pub struct S(u16); //~ ERROR type has conflicting packed and align representation hints #[repr(packed, align(0x100))] pub union U { //~ ERROR type has conflicting packed and align representation hints u: u16 } static B: U = U { u: 0 }; static A: S = S(0); </ins> fn main() {}


LL | | } | |_^ <del> error: aborting due to 10 previous errors </del> <ins> error[E0587]: type has conflicting packed and align representation hints --> $DIR/conflicting-repr-hints.rs:70:1 | LL | pub struct S(u16); | ^^^^^^^^^^^^^^^^^^ error[E0587]: type has conflicting packed and align representation hints --> $DIR/conflicting-repr-hints.rs:73:1 | LL | / pub union U { LL | |     u: u16 LL | | } | |_^ error: aborting due to 12 previous errors </ins> Some errors have detailed explanations: E0566, E0587, E0634. For more information about an error, try `rustc --explain E0566`.


#[unstable(feature = "str_internals", issue = "none")] pub use validations::next_code_point; <ins> #[unstable(feature = "str_internals", issue = "none")] pub use validations::utf8_char_width; </ins> use iter::MatchIndicesInternal; use iter::SplitInternal; use iter::{MatchesInternal, SplitNInternal};


use crate::sys::c; use crate::sys::cvt; use crate::sys::handle::Handle; <ins> use core::str::utf8_char_width; </ins> // Don't cache handles but get them fresh for every read/write. This allows us to track changes to // the value over time (such as if a process calls `SetStdHandle` while it's running). See #40490. pub struct Stdin { surrogate: u16, } <del> pub struct Stdout; pub struct Stderr; </del> <ins> pub struct Stdout { incomplete_utf8: IncompleteUtf8, } pub struct Stderr { incomplete_utf8: IncompleteUtf8, } struct IncompleteUtf8 { bytes: [u8; 4], len: u8, } </ins> // Apparently Windows doesn't handle large reads on stdin or writes to stdout/stderr well (see // #13304 for details).


unsafe { c::GetConsoleMode(handle, &mut mode) != 0 } } <del> fn write(handle_id: c::DWORD, data: &[u8]) -> io::Result<usize> { </del> <ins> fn write( handle_id: c::DWORD, data: &[u8], incomplete_utf8: &mut IncompleteUtf8, ) -> io::Result<usize> { if data.is_empty() { return Ok(0); } </ins> let handle = get_handle(handle_id)?; if !is_console(handle) { let handle = Handle::new(handle);


return ret; } <del> // As the console is meant for presenting text, we assume bytes of `data` come from a string // and are encoded as UTF-8, which needs to be encoded as UTF-16. </del> <ins> if incomplete_utf8.len > 0 { assert!( incomplete_utf8.len < 4, "Unexpected number of bytes for incomplete UTF-8 codepoint." ); if data[0] >> 6 != 0b10 { incomplete_utf8.len = 0; // not a continuation byte - reject return Err(io::Error::new_const( io::ErrorKind::InvalidData, &"Windows stdio in console mode does not support writing non-UTF-8 byte sequences", )); } incomplete_utf8.bytes[incomplete_utf8.len as usize] = data[0]; incomplete_utf8.len += 1; let char_width = utf8_char_width(incomplete_utf8.bytes[0]); if (incomplete_utf8.len as usize) < char_width { // more bytes needed return Ok(1); } let s = str::from_utf8(&incomplete_utf8.bytes[0..incomplete_utf8.len as usize]); incomplete_utf8.len = 0; match s { Ok(s) => { assert_eq!(char_width, s.len()); let written = write_valid_utf8_to_console(handle, s)?; assert_eq!(written, s.len()); // guaranteed by write_valid_utf8_to_console() for single codepoint writes return Ok(1); } Err(_) => { return Err(io::Error::new_const( io::ErrorKind::InvalidData, &"Windows stdio in console mode does not support writing non-UTF-8 byte sequences", )); } } } // As the console is meant for presenting text, we assume bytes of `data` are encoded as UTF-8, // which needs to be encoded as UTF-16. </ins> // // If the data is not valid UTF-8 we write out as many bytes as are valid. <del> // Only when there are no valid bytes (which will happen on the next call), return an error. </del> <ins> // If the first byte is invalid it is either first byte of a multi-byte sequence but the // provided byte slice is too short or it is the first byte of an invalide multi-byte sequence. </ins> let len = cmp::min(data.len(), MAX_BUFFER_SIZE / 2); let utf8 = match str::from_utf8(&data[..len]) { Ok(s) => s, Err(ref e) if e.valid_up_to() == 0 => { <del> return Err(io::Error::new_const( io::ErrorKind::InvalidData, &"Windows stdio in console mode does not support writing non-UTF-8 byte sequences", )); </del> <ins> let first_byte_char_width = utf8_char_width(data[0]); if first_byte_char_width > 1 && data.len() < first_byte_char_width { incomplete_utf8.bytes[0] = data[0]; incomplete_utf8.len = 1; return Ok(1); } else { return Err(io::Error::new_const( io::ErrorKind::InvalidData, &"Windows stdio in console mode does not support writing non-UTF-8 byte sequences", )); } </ins> } Err(e) => str::from_utf8(&data[..e.valid_up_to()]).unwrap(), }; <ins> write_valid_utf8_to_console(handle, utf8) } fn write_valid_utf8_to_console(handle: c::HANDLE, utf8: &str) -> io::Result<usize> { </ins> let mut utf16 = [0u16; MAX_BUFFER_SIZE / 2]; let mut len_utf16 = 0; for (chr, dest) in utf8.encode_utf16().zip(utf16.iter_mut()) {


Ok(written) } <ins> impl IncompleteUtf8 { pub const fn new() -> IncompleteUtf8 { IncompleteUtf8 { bytes: [0; 4], len: 0 } } } </ins> impl Stdout { pub const fn new() -> Stdout { <del> Stdout </del> <ins> Stdout { incomplete_utf8: IncompleteUtf8::new() } </ins> } } impl io::Write for Stdout { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { <del> write(c::STD_OUTPUT_HANDLE, buf) </del> <ins> write(c::STD_OUTPUT_HANDLE, buf, &mut self.incomplete_utf8) </ins> } fn flush(&mut self) -> io::Result<()> {


impl Stderr { pub const fn new() -> Stderr { <del> Stderr </del> <ins> Stderr { incomplete_utf8: IncompleteUtf8::new() } </ins> } } impl io::Write for Stderr { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { <del> write(c::STD_ERROR_HANDLE, buf) </del> <ins> write(c::STD_ERROR_HANDLE, buf, &mut self.incomplete_utf8) </ins> } fn flush(&mut self) -> io::Result<()> {


let mut inserted = FxHashSet::default(); items.extend(doc.foreigns.iter().map(|(item, renamed)| { let item = clean_maybe_renamed_foreign_item(cx, item, *renamed); <del> if let Some(name) = item.name { </del> <ins> if let Some(name) = item.name && !item.attrs.lists(sym::doc).has_word(sym::hidden) { </ins> inserted.insert((item.type_(), name)); } item })); <del> items.extend(doc.mods.iter().map(|x| { inserted.insert((ItemType::Module, x.name)); clean_doc_module(x, cx) </del> <ins> items.extend(doc.mods.iter().filter_map(|x| { if !inserted.insert((ItemType::Module, x.name)) { return None; } let item = clean_doc_module(x, cx); if item.attrs.lists(sym::doc).has_word(sym::hidden) { // Hidden modules are stripped at a later stage. // If a hidden module has the same name as a visible one, we want // to keep both of them around. inserted.remove(&(ItemType::Module, x.name)); } Some(item) </ins> })); // Split up imports from all other items.


} let v = clean_maybe_renamed_item(cx, item, *renamed); for item in &v { <del> if let Some(name) = item.name { </del> <ins> if let Some(name) = item.name && !item.attrs.lists(sym::doc).has_word(sym::hidden) { </ins> inserted.insert((item.type_(), name)); } }


self.inside_public_path &= self.cx.tcx.visibility(def_id).is_public(); for &i in m.item_ids { let item = self.cx.tcx.hir().item(i); <ins> if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) { continue; } </ins> self.visit_item(item, None, &mut om); } <ins> for &i in m.item_ids { let item = self.cx.tcx.hir().item(i); // To match the way import precedence works, visit glob imports last. // Later passes in rustdoc will de-duplicate by name and kind, so if glob- // imported items appear last, then they'll be the ones that get discarded. if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) { self.visit_item(item, None, &mut om); } } </ins> self.inside_public_path = orig_inside_public_path; om }


<ins> // https://github.com/rust-lang/rust/pull/83872#issuecomment-820101008 #![crate_name="foo"] mod sub4 { /// 0 pub const X: usize = 0; pub mod inner { pub use super::*; /// 1 pub const X: usize = 1; } } #[doc(inline)] pub use sub4::inner::*; // @has 'foo/index.html' // @has - '//div[@class="item-right docblock-short"]' '1' // @!has - '//div[@class="item-right docblock-short"]' '0' fn main() { assert_eq!(X, 1); } </ins>


<ins> // @has 'glob_shadowing/index.html' // @count - '//div[@class="item-left module-item"]' 6 // @!has - '//div[@class="item-right docblock-short"]' 'sub1::describe' // @has - '//div[@class="item-right docblock-short"]' 'sub2::describe' // @!has - '//div[@class="item-right docblock-short"]' 'sub1::describe2' // @!has - '//div[@class="item-right docblock-short"]' 'sub1::prelude' // @has - '//div[@class="item-right docblock-short"]' 'mod::prelude' // @has - '//div[@class="item-right docblock-short"]' 'sub1::Foo (struct)' // @has - '//div[@class="item-right docblock-short"]' 'mod::Foo (function)' // @has - '//div[@class="item-right docblock-short"]' 'sub4::inner::X' // @has 'glob_shadowing/fn.describe.html' // @has - '//div[@class="docblock"]' 'sub2::describe' mod sub1 { // this should be shadowed by sub2::describe /// sub1::describe pub fn describe() -> &'static str { "sub1::describe" } // this should be shadowed by mod::prelude /// sub1::prelude pub mod prelude { } // this should *not* be shadowed, because sub1::Foo and mod::Foo are in different namespaces /// sub1::Foo (struct) pub struct Foo; // this should be shadowed, // because both sub1::describe2 and sub3::describe2 are from glob reexport /// sub1::describe2 pub fn describe2() -> &'static str { "sub1::describe2" } } mod sub2 { /// sub2::describe pub fn describe() -> &'static str { "sub2::describe" } } mod sub3 { // this should be shadowed // because both sub1::describe2 and sub3::describe2 are from glob reexport /// sub3::describe2 pub fn describe2() -> &'static str { "sub3::describe2" } } mod sub4 { // this should be shadowed by sub4::inner::X /// sub4::X pub const X: usize = 0; pub mod inner { pub use super::*; /// sub4::inner::X pub const X: usize = 1; } } /// mod::Foo (function) pub fn Foo() {} #[doc(inline)] pub use sub2::describe; #[doc(inline)] pub use sub1::*; #[doc(inline)] pub use sub3::*; #[doc(inline)] pub use sub4::inner::*; /// mod::prelude pub mod prelude {} </ins>


<ins> #![crate_name = "foo"] pub mod sub { pub struct Item; pub mod prelude { pub use super::Item; } } #[doc(inline)] pub use sub::*; // @count foo/index.html '//a[@class="mod"][@title="foo::prelude mod"]' 1 // @count foo/prelude/index.html '//div[@class="item-row"]' 0 pub mod prelude {} </ins>


<ins> #![crate_name = "foo"] pub mod sub { pub struct Item; pub mod prelude { pub use super::Item; } } // @count foo/index.html '//a[@class="mod"][@title="foo::prelude mod"]' 1 // @count foo/prelude/index.html '//div[@class="item-row"]' 0 pub mod prelude {} #[doc(inline)] pub use sub::*; </ins>


def update(self): # type: () -> None table = self.table() <del> capacity = table.GetChildMemberWithName("bucket_mask").GetValueAsUnsigned() + 1 ctrl = table.GetChildMemberWithName("ctrl").GetChildAtIndex(0) </del> <ins> inner_table = table.GetChildMemberWithName("table") </ins> <del> self.size = table.GetChildMemberWithName("items").GetValueAsUnsigned() </del> <ins> capacity = inner_table.GetChildMemberWithName("bucket_mask").GetValueAsUnsigned() + 1 ctrl = inner_table.GetChildMemberWithName("ctrl").GetChildAtIndex(0) self.size = inner_table.GetChildMemberWithName("items").GetValueAsUnsigned() </ins> self.pair_type = table.type.template_args[0] if self.pair_type.IsTypedefType(): self.pair_type = self.pair_type.GetTypedefedType() self.pair_type_size = self.pair_type.GetByteSize() <del> self.new_layout = not table.GetChildMemberWithName("data").IsValid() </del> <ins> self.new_layout = not inner_table.GetChildMemberWithName("data").IsValid() </ins> if self.new_layout: self.data_ptr = ctrl.Cast(self.pair_type.GetPointerType()) else: <del> self.data_ptr = table.GetChildMemberWithName("data").GetChildAtIndex(0) </del> <ins> self.data_ptr = inner_table.GetChildMemberWithName("data").GetChildAtIndex(0) </ins> u8_type = self.valobj.GetTarget().GetBasicType(eBasicTypeUnsignedChar) u8_type_size = self.valobj.GetTarget().GetBasicType(eBasicTypeUnsignedChar).GetByteSize()


# HashSet wraps either std HashMap or hashbrown::HashSet, which both # wrap hashbrown::HashMap, so either way we "unwrap" twice. hashbrown_hashmap = self.valobj.GetChildAtIndex(0).GetChildAtIndex(0) <del> return hashbrown_hashmap.GetChildMemberWithName("table").GetChildMemberWithName("table") </del> <ins> return hashbrown_hashmap.GetChildMemberWithName("table") </ins> def has_children(self): # type: () -> bool


/// scratch space that it may use however it wants. It will generally just do /// whatever is most efficient or otherwise easy to implement. Do not rely on /// removed data to be erased for security purposes. Even if you drop a `Vec`, its <del> /// buffer may simply be reused by another `Vec`. Even if you zero a `Vec`'s memory </del> <ins> /// buffer may simply be reused by another allocation. Even if you zero a `Vec`'s memory </ins> /// first, that might not actually happen because the optimizer does not consider /// this a side-effect that must be preserved. There is one case which we will /// not break, however: using `unsafe` code to write to the excess capacity,


val } <ins> fn emit_s390x_va_arg<'ll, 'tcx>( bx: &mut Builder<'_, 'll, 'tcx>, list: OperandRef<'tcx, &'ll Value>, target_ty: Ty<'tcx>, ) -> &'ll Value { // Implementation of the s390x ELF ABI calling convention for va_args see // https://github.com/IBM/s390x-abi (chapter 1.2.4) let va_list_addr = list.immediate(); let va_list_layout = list.deref(bx.cx).layout; let va_list_ty = va_list_layout.llvm_type(bx); let layout = bx.cx.layout_of(target_ty); let in_reg = bx.append_sibling_block("va_arg.in_reg"); let in_mem = bx.append_sibling_block("va_arg.in_mem"); let end = bx.append_sibling_block("va_arg.end"); // FIXME: vector ABI not yet supported. let target_ty_size = bx.cx.size_of(target_ty).bytes(); let indirect: bool = target_ty_size > 8 || !target_ty_size.is_power_of_two(); let unpadded_size = if indirect { 8 } else { target_ty_size }; let padded_size = 8; let padding = padded_size - unpadded_size; let gpr_type = indirect || !layout.is_single_fp_element(bx.cx); let (max_regs, reg_count_field, reg_save_index, reg_padding) = if gpr_type { (5, 0, 2, padding) } else { (4, 1, 16, 0) }; // Check whether the value was passed in a register or in memory. let reg_count = bx.struct_gep( va_list_ty, va_list_addr, va_list_layout.llvm_field_index(bx.cx, reg_count_field), ); let reg_count_v = bx.load(bx.type_i64(), reg_count, Align::from_bytes(8).unwrap()); let use_regs = bx.icmp(IntPredicate::IntULT, reg_count_v, bx.const_u64(max_regs)); bx.cond_br(use_regs, in_reg, in_mem); // Emit code to load the value if it was passed in a register. bx.switch_to_block(in_reg); // Work out the address of the value in the register save area. let reg_ptr = bx.struct_gep(va_list_ty, va_list_addr, va_list_layout.llvm_field_index(bx.cx, 3)); let reg_ptr_v = bx.load(bx.type_i8p(), reg_ptr, bx.tcx().data_layout.pointer_align.abi); let scaled_reg_count = bx.mul(reg_count_v, bx.const_u64(8)); let reg_off = bx.add(scaled_reg_count, bx.const_u64(reg_save_index * 8 + reg_padding)); let reg_addr = bx.gep(bx.type_i8(), reg_ptr_v, &[reg_off]); // Update the register count. let new_reg_count_v = bx.add(reg_count_v, bx.const_u64(1)); bx.store(new_reg_count_v, reg_count, Align::from_bytes(8).unwrap()); bx.br(end); // Emit code to load the value if it was passed in memory. bx.switch_to_block(in_mem); // Work out the address of the value in the argument overflow area. let arg_ptr = bx.struct_gep(va_list_ty, va_list_addr, va_list_layout.llvm_field_index(bx.cx, 2)); let arg_ptr_v = bx.load(bx.type_i8p(), arg_ptr, bx.tcx().data_layout.pointer_align.abi); let arg_off = bx.const_u64(padding); let mem_addr = bx.gep(bx.type_i8(), arg_ptr_v, &[arg_off]); // Update the argument overflow area pointer. let arg_size = bx.cx().const_u64(padded_size); let new_arg_ptr_v = bx.inbounds_gep(bx.type_i8(), arg_ptr_v, &[arg_size]); bx.store(new_arg_ptr_v, arg_ptr, bx.tcx().data_layout.pointer_align.abi); bx.br(end); // Return the appropriate result. bx.switch_to_block(end); let val_addr = bx.phi(bx.type_i8p(), &[reg_addr, mem_addr], &[in_reg, in_mem]); let val_type = layout.llvm_type(bx); let val_addr = if indirect { let ptr_type = bx.cx.type_ptr_to(val_type); let ptr_addr = bx.bitcast(val_addr, bx.cx.type_ptr_to(ptr_type)); bx.load(ptr_type, ptr_addr, bx.tcx().data_layout.pointer_align.abi) } else { bx.bitcast(val_addr, bx.cx.type_ptr_to(val_type)) }; bx.load(val_type, val_addr, layout.align.abi) } </ins> pub(super) fn emit_va_arg<'ll, 'tcx>( bx: &mut Builder<'_, 'll, 'tcx>, addr: OperandRef<'tcx, &'ll Value>,


emit_ptr_va_arg(bx, addr, target_ty, false, Align::from_bytes(8).unwrap(), true) } "aarch64" => emit_aapcs_va_arg(bx, addr, target_ty), <ins> "s390x" => emit_s390x_va_arg(bx, addr, target_ty), </ins> // Windows x86_64 "x86_64" if target.is_like_windows => { let target_ty_size = bx.cx.size_of(target_ty).bytes();


/// Basic implementation of a `va_list`. // The name is WIP, using `VaListImpl` for now. #[cfg(any( <del> all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "x86_64")), </del> <ins> all( not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "s390x"), not(target_arch = "x86_64") ), </ins> all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios")), target_family = "wasm", target_arch = "asmjs",


_marker: PhantomData<&'f mut &'f c_void>, } <ins> /// s390x ABI implementation of a `va_list`. #[cfg(target_arch = "s390x")] #[repr(C)] #[derive(Debug)] #[unstable( feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on  all supported platforms", issue = "44930" )] #[lang = "va_list"] pub struct VaListImpl<'f> { gpr: i64, fpr: i64, overflow_arg_area: *mut c_void, reg_save_area: *mut c_void, _marker: PhantomData<&'f mut &'f c_void>, } </ins> /// x86_64 ABI implementation of a `va_list`. #[cfg(all(target_arch = "x86_64", not(target_os = "uefi"), not(windows)))] #[repr(C)]


all( not(target_arch = "aarch64"), not(target_arch = "powerpc"), <ins> not(target_arch = "s390x"), </ins> not(target_arch = "x86_64") ), all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios")),


inner: VaListImpl<'f>, #[cfg(all( <del> any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"), </del> <ins> any( target_arch = "aarch64", target_arch = "powerpc", target_arch = "s390x", target_arch = "x86_64" ), </ins> any(not(target_arch = "aarch64"), not(any(target_os = "macos", target_os = "ios"))), not(target_family = "wasm"), not(target_arch = "asmjs"),


} #[cfg(any( <del> all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "x86_64")), </del> <ins> all( not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "s390x"), not(target_arch = "x86_64") ), </ins> all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios")), target_family = "wasm", target_arch = "asmjs",


} #[cfg(all( <del> any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"), </del> <ins> any( target_arch = "aarch64", target_arch = "powerpc", target_arch = "s390x", target_arch = "x86_64" ), </ins> any(not(target_arch = "aarch64"), not(any(target_os = "macos", target_os = "ios"))), not(target_family = "wasm"), not(target_arch = "asmjs"),


use rustc_middle::middle::privacy::AccessLevels; use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; use rustc_resolve as resolve; <ins> use rustc_resolve::Namespace::TypeNS; </ins> use rustc_session::config::{self, CrateType, ErrorOutputType}; use rustc_session::lint; use rustc_session::DiagnosticOutput; use rustc_session::Session; <ins> use rustc_span::def_id::CRATE_DEF_INDEX; </ins> use rustc_span::source_map; use rustc_span::symbol::sym; <del> use rustc_span::Span; </del> <ins> use rustc_span::{Span, DUMMY_SP}; </ins> use std::cell::RefCell; use std::lazy::SyncLazy;


} crate fn create_resolver<'a>( <ins> externs: config::Externs, </ins> queries: &Queries<'a>, sess: &Session, ) -> Rc<RefCell<interface::BoxedResolver>> { let (krate, resolver, _) = &*abort_on_err(queries.expansion(), sess).peek(); let resolver = resolver.clone(); <del> crate::passes::collect_intra_doc_links::load_intra_link_crates(resolver, krate) </del> <ins> let resolver = crate::passes::collect_intra_doc_links::load_intra_link_crates(resolver, krate); // FIXME: somehow rustdoc is still missing crates even though we loaded all // the known necessary crates. Load them all unconditionally until we find a way to fix this. // DO NOT REMOVE THIS without first testing on the reproducer in // https://github.com/jyn514/objr/commit/edcee7b8124abf0e4c63873e8422ff81beb11ebb let extern_names: Vec<String> = externs .iter() .filter(|(_, entry)| entry.add_prelude) .map(|(name, _)| name) .cloned() .collect(); resolver.borrow_mut().access(|resolver| { sess.time("load_extern_crates", || { for extern_name in &extern_names { debug!("loading extern crate {}", extern_name); if let Err(()) = resolver .resolve_str_path_error( DUMMY_SP, extern_name, TypeNS, LocalDefId { local_def_index: CRATE_DEF_INDEX }.to_def_id(), ) { warn!("unable to resolve external crate {} (do you have an unused `--extern` crate?)", extern_name) } } }); }); resolver </ins> } crate fn run_global_ctxt(


let default_passes = options.default_passes; let output_format = options.output_format; // FIXME: fix this clone (especially render_options) <ins> let externs = options.externs.clone(); </ins> let manual_passes = options.manual_passes.clone(); let render_options = options.render_options.clone(); let scrape_examples_options = options.scrape_examples_options.clone();


// We need to hold on to the complete resolver, so we cause everything to be // cloned for the analysis passes to use. Suboptimal, but necessary in the // current architecture. <del> let resolver = core::create_resolver(queries, sess); </del> <ins> let resolver = core::create_resolver(externs, queries, sess); </ins> if sess.has_errors() { sess.fatal("Compilation failed, aborting rustdoc");


<ins> use ast::visit; </ins> use rustc_ast as ast; use rustc_hir::def::Namespace::TypeNS; use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};


let mut loader = IntraLinkCrateLoader { current_mod: CRATE_DEF_ID, resolver }; // `walk_crate` doesn't visit the crate itself for some reason. loader.load_links_in_attrs(&krate.attrs, krate.span); <del> ast::visit::walk_crate(&mut loader, krate); </del> <ins> visit::walk_crate(&mut loader, krate); </ins> loader.resolver }


} } <del> impl ast::visit::Visitor<'_> for IntraLinkCrateLoader { </del> <ins> impl visit::Visitor<'_> for IntraLinkCrateLoader { fn visit_foreign_item(&mut self, item: &ast::ForeignItem) { self.load_links_in_attrs(&item.attrs, item.span); visit::walk_foreign_item(self, item) } </ins> fn visit_item(&mut self, item: &ast::Item) { use rustc_ast_lowering::ResolverAstLowering;


let old_mod = mem::replace(&mut self.current_mod, new_mod); self.load_links_in_attrs(&item.attrs, item.span); <del> ast::visit::walk_item(self, item); </del> <ins> visit::walk_item(self, item); </ins> self.current_mod = old_mod; } else { self.load_links_in_attrs(&item.attrs, item.span); <del> ast::visit::walk_item(self, item); </del> <ins> visit::walk_item(self, item); </ins> } } <ins> // NOTE: if doc-comments are ever allowed on function parameters, this will have to implement `visit_param` too. fn visit_assoc_item(&mut self, item: &ast::AssocItem, ctxt: visit::AssocCtxt) { self.load_links_in_attrs(&item.attrs, item.span); visit::walk_assoc_item(self, item, ctxt) } fn visit_field_def(&mut self, field: &ast::FieldDef) { self.load_links_in_attrs(&field.attrs, field.span); visit::walk_field_def(self, field) } fn visit_variant(&mut self, v: &ast::Variant) { self.load_links_in_attrs(&v.attrs, v.span); visit::walk_variant(self, v) } </ins> }


<ins> // check-pass // aux-crate:dep1=dep1.rs // aux-crate:dep2=dep2.rs // aux-crate:dep3=dep3.rs // aux-crate:dep4=dep4.rs #![deny(rustdoc::broken_intra_doc_links)] pub trait Trait { /// [dep1] type Item; } pub struct S { /// [dep2] pub x: usize, } extern "C" { /// [dep3] pub fn printf(); } pub enum E { /// [dep4] A } </ins>


pub const TRUE: BOOL = 1; pub const FALSE: BOOL = 0; <ins> pub const CSTR_LESS_THAN: c_int = 1; pub const CSTR_EQUAL: c_int = 2; pub const CSTR_GREATER_THAN: c_int = 3; </ins> pub const FILE_ATTRIBUTE_READONLY: DWORD = 0x1; pub const FILE_ATTRIBUTE_DIRECTORY: DWORD = 0x10; pub const FILE_ATTRIBUTE_REPARSE_POINT: DWORD = 0x400;


pub fn ReleaseSRWLockShared(SRWLock: PSRWLOCK); pub fn TryAcquireSRWLockExclusive(SRWLock: PSRWLOCK) -> BOOLEAN; pub fn TryAcquireSRWLockShared(SRWLock: PSRWLOCK) -> BOOLEAN; <ins> pub fn CompareStringOrdinal( lpString1: LPCWSTR, cchCount1: c_int, lpString2: LPCWSTR, cchCount2: c_int, bIgnoreCase: BOOL, ) -> c_int; </ins> } // Functions that aren't available on every version of Windows that we support,


mod tests; use crate::borrow::Borrow; <ins> use crate::cmp; </ins> use crate::collections::BTreeMap; use crate::convert::{TryFrom, TryInto}; use crate::env;


// Command //////////////////////////////////////////////////////////////////////////////// <del> #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] </del> <ins> #[derive(Clone, Debug, Eq)] </ins> #[doc(hidden)] <del> pub struct EnvKey(OsString); </del> <ins> pub struct EnvKey { os_string: OsString, // This stores a UTF-16 encoded string to workaround the mismatch between // Rust's OsString (WTF-8) and the Windows API string type (UTF-16). // Normally converting on every API call is acceptable but here // `c::CompareStringOrdinal` will be called for every use of `==`. utf16: Vec<u16>, } // Comparing Windows environment variable keys[1] are behaviourally the // composition of two operations[2]: // // 1. Case-fold both strings. This is done using a language-independent // uppercase mapping that's unique to Windows (albeit based on data from an // older Unicode spec). It only operates on individual UTF-16 code units so // surrogates are left unchanged. This uppercase mapping can potentially change // between Windows versions. // // 2. Perform an ordinal comparison of the strings. A comparison using ordinal // is just a comparison based on the numerical value of each UTF-16 code unit[3]. // // Because the case-folding mapping is unique to Windows and not guaranteed to // be stable, we ask the OS to compare the strings for us. This is done by // calling `CompareStringOrdinal`[4] with `bIgnoreCase` set to `TRUE`. // // [1] https://docs.microsoft.com/en-us/dotnet/standard/base-types/best-practices-strings#choosing-a-stringcomparison-member-for-your-method-call // [2] https://docs.microsoft.com/en-us/dotnet/standard/base-types/best-practices-strings#stringtoupper-and-stringtolower // [3] https://docs.microsoft.com/en-us/dotnet/api/system.stringcomparison?view=net-5.0#System_StringComparison_Ordinal // [4] https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-comparestringordinal impl Ord for EnvKey { fn cmp(&self, other: &Self) -> cmp::Ordering { unsafe { let result = c::CompareStringOrdinal( self.utf16.as_ptr(), self.utf16.len() as _, other.utf16.as_ptr(), other.utf16.len() as _, c::TRUE, ); match result { c::CSTR_LESS_THAN => cmp::Ordering::Less, c::CSTR_EQUAL => cmp::Ordering::Equal, c::CSTR_GREATER_THAN => cmp::Ordering::Greater, // `CompareStringOrdinal` should never fail so long as the parameters are correct. _ => panic!("comparing environment keys failed: {}", Error::last_os_error()), } } } } impl PartialOrd for EnvKey { fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { Some(self.cmp(other)) } } impl PartialEq for EnvKey { fn eq(&self, other: &Self) -> bool { if self.utf16.len() != other.utf16.len() { false } else { self.cmp(other) == cmp::Ordering::Equal } } } // Environment variable keys should preserve their original case even though // they are compared using a caseless string mapping. </ins> impl From<OsString> for EnvKey { <del> fn from(mut k: OsString) -> Self { k.make_ascii_uppercase(); EnvKey(k) </del> <ins> fn from(k: OsString) -> Self { EnvKey { utf16: k.encode_wide().collect(), os_string: k } </ins> } } impl From<EnvKey> for OsString { fn from(k: EnvKey) -> Self { <del> k.0 </del> <ins> k.os_string </ins> } } impl Borrow<OsStr> for EnvKey { fn borrow(&self) -> &OsStr { <del> &self.0 </del> <ins> &self.os_string </ins> } } impl AsRef<OsStr> for EnvKey { fn as_ref(&self) -> &OsStr { <del> &self.0 </del> <ins> &self.os_string </ins> } }


let mut blk = Vec::new(); for (k, v) in env { <del> blk.extend(ensure_no_nuls(k.0)?.encode_wide()); </del> <ins> ensure_no_nuls(k.os_string)?; blk.extend(k.utf16); </ins> blk.push('=' as u16); blk.extend(ensure_no_nuls(v)?.encode_wide()); blk.push(0);


use super::make_command_line; <ins> use crate::env; </ins> use crate::ffi::{OsStr, OsString}; <ins> use crate::process::Command; </ins> #[test] fn test_make_command_line() {


""u{03c0}u{042f}u{97f3}u{00e6}u{221e}"" ); } <ins> // On Windows, environment args are case preserving but comparisons are case-insensitive. // See: #85242 #[test] fn windows_env_unicode_case() { let test_cases = [ ("ä", "Ä"), ("ß", "SS"), ("Ä", "Ö"), ("Ä", "Ö"), ("I", "İ"), ("I", "i"), ("I", "ı"), ("i", "I"), ("i", "İ"), ("i", "ı"), ("İ", "I"), ("İ", "i"), ("İ", "ı"), ("ı", "I"), ("ı", "i"), ("ı", "İ"), ("ä", "Ä"), ("ß", "SS"), ("Ä", "Ö"), ("Ä", "Ö"), ("I", "İ"), ("I", "i"), ("I", "ı"), ("i", "I"), ("i", "İ"), ("i", "ı"), ("İ", "I"), ("İ", "i"), ("İ", "ı"), ("ı", "I"), ("ı", "i"), ("ı", "İ"), ]; // Test that `cmd.env` matches `env::set_var` when setting two strings that // may (or may not) be case-folded when compared. for (a, b) in test_cases.iter() { let mut cmd = Command::new("cmd"); cmd.env(a, "1"); cmd.env(b, "2"); env::set_var(a, "1"); env::set_var(b, "2"); for (key, value) in cmd.get_envs() { assert_eq!( env::var(key).ok(), value.map(|s| s.to_string_lossy().into_owned()), "command environment mismatch: {} {}", a, b ); } } } </ins>


), ); <del> llvm::set_linkage(llfn, llvm::Linkage::WeakAnyLinkage); llvm::set_visibility(llfn, llvm::Visibility::Hidden); </del> <ins> llvm::set_linkage(llfn, llvm::Linkage::PrivateLinkage); llvm::set_visibility(llfn, llvm::Visibility::Default); </ins> assert!(cx.instances.borrow_mut().insert(instance, llfn).is_none());


<ins> ../coverage/issue-85461.rs: 1|       |// Regression test for #85461: MSVC sometimes fail to link with dead code and #[inline(always)] 2|       | 3|       |extern crate inline_always_with_dead_code; 4|       | 5|       |use inline_always_with_dead_code::{bar, baz}; 6|       | 7|      1|fn main() { 8|      1|    bar::call_me(); 9|      1|    baz::call_me(); 10|      1|} ../coverage/lib/inline_always_with_dead_code.rs: 1|       |// compile-flags: -Zinstrument-coverage -Ccodegen-units=4 -Copt-level=0 2|       | 3|       |#![allow(dead_code)] 4|       | 5|       |mod foo { 6|       |    #[inline(always)] 7|      2|    pub fn called() { } 8|       | 9|      0|    fn uncalled() { } 10|       |} 11|       | 12|       |pub mod bar { 13|      1|    pub fn call_me() { 14|      1|        super::foo::called(); 15|      1|    } 16|       |} 17|       | 18|       |pub mod baz { 19|      1|    pub fn call_me() { 20|      1|        super::foo::called(); 21|      1|    } 22|       |} </ins>


<ins> // Regression test for #85461: MSVC sometimes fail to link with dead code and #[inline(always)] extern crate inline_always_with_dead_code; use inline_always_with_dead_code::{bar, baz}; fn main() { bar::call_me(); baz::call_me(); } </ins>


<ins> // compile-flags: -Zinstrument-coverage -Ccodegen-units=4 -Copt-level=0 #![allow(dead_code)] mod foo { #[inline(always)] pub fn called() { } fn uncalled() { } } pub mod bar { pub fn call_me() { super::foo::called(); } } pub mod baz { pub fn call_me() { super::foo::called(); } } </ins>


<ins> // compile-flags: -Zinstrument-coverage -Ccodegen-units=4 --crate-type dylib -Copt-level=0 // build-pass // needs-profiler-support // Regression test for #85461 where MSVC sometimes fails to link instrument-coverage binaries // with dead code and #[inline(always)]. #![allow(dead_code)] mod foo { #[inline(always)] pub fn called() { } fn uncalled() { } } pub mod bar { pub fn call_me() { super::foo::called(); } } pub mod baz { pub fn call_me() { super::foo::called(); } } </ins>


<ins> // min-llvm-version: 15.0.0 // compile-flags: -O #![crate_type = "lib"] #[no_mangle] pub fn u16_be_to_arch(mut data: [u8; 2]) -> [u8; 2] { // CHECK-LABEL: @u16_be_to_arch // CHECK: @llvm.bswap.i16 data.reverse(); data } #[no_mangle] pub fn u32_be_to_arch(mut data: [u8; 4]) -> [u8; 4] { // CHECK-LABEL: @u32_be_to_arch // CHECK: @llvm.bswap.i32 data.reverse(); data } </ins>


let size = u64::try_from(self.force_bits(size, pointer_size)?).unwrap(); let align = vtable.read_ptr_sized(pointer_size * 2)?.check_init()?; let align = u64::try_from(self.force_bits(align, pointer_size)?).unwrap(); <ins> let align = Align::from_bytes(align) .map_err(|e| err_ub_format!("invalid vtable: alignment {}", e))?; </ins> if size >= self.tcx.data_layout.obj_size_bound() { throw_ub_format!(


size is bigger than largest supported object" ); } <del> Ok((Size::from_bytes(size), Align::from_bytes(align).unwrap())) </del> <ins> Ok((Size::from_bytes(size), align)) </ins> } }


<ins> // This test contains code with incorrect vtables in a const context: // - from issue 86132: a trait object with invalid alignment caused an ICE in const eval, and now //   triggers an error // - a similar test that triggers a previously-untested const UB error: emitted close to the above //   error, it checks the correctness of the size trait Trait {} const INVALID_VTABLE_ALIGNMENT: &dyn Trait = unsafe { std::mem::transmute((&92u8, &[0usize, 1usize, 1000usize])) }; //~^ ERROR any use of this value will cause an error //~| WARNING this was previously accepted by the compiler //~| invalid vtable: alignment `1000` is not a power of 2 const INVALID_VTABLE_SIZE: &dyn Trait = unsafe { std::mem::transmute((&92u8, &[1usize, usize::MAX, 1usize])) }; //~^ ERROR any use of this value will cause an error //~| WARNING this was previously accepted by the compiler //~| invalid vtable: size is bigger than largest supported object fn main() {} </ins>


<ins> error: any use of this value will cause an error --> $DIR/ub-incorrect-vtable.rs:10:14 | LL | / const INVALID_VTABLE_ALIGNMENT: &dyn Trait = LL | |     unsafe { std::mem::transmute((&92u8, &[0usize, 1usize, 1000usize])) }; | |______________^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^__- |                | |                invalid vtable: alignment `1000` is not a power of 2 | = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> error: any use of this value will cause an error --> $DIR/ub-incorrect-vtable.rs:16:14 | LL | / const INVALID_VTABLE_SIZE: &dyn Trait = LL | |     unsafe { std::mem::transmute((&92u8, &[1usize, usize::MAX, 1usize])) }; | |______________^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^__- |                | |                invalid vtable: size is bigger than largest supported object | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> error: aborting due to 2 previous errors </ins>


} w.write_str(")"); }  w.write_str("
");   w.write_str(""); render_stability_since(w, variant, it, cx.tcx()); w.write_str("
");  document(w, cx, variant, Some(it)); document_non_exhaustive(w, variant);


w.write_str("

"); toggle_close(w); }  render_stability_since(w, variant, it, cx.tcx());  } } let def_id = it.def_id.expect_real();


background: transparent; } <ins> .small-section-header { display: flex; justify-content: space-between; position: relative; } </ins> .small-section-header:hover > .anchor { display: initial; }


let sz_a = self.a.size(); if A::MAY_HAVE_SIDE_EFFECT && sz_a > self.len { for _ in 0..sz_a - self.len { <ins> self.a_len -= 1; </ins> self.a.next_back(); } <del> self.a_len = self.len; </del> <ins> debug_assert_eq!(self.a_len, self.len); </ins> } let sz_b = self.b.size(); if B::MAY_HAVE_SIDE_EFFECT && sz_b > self.len {


} #[test] <ins> #[cfg(panic = "unwind")] fn test_zip_trusted_random_access_next_back_drop() { use std::panic::catch_unwind; use std::panic::AssertUnwindSafe; let mut counter = 0; let it = [42].iter().map(|e| { let c = counter; counter += 1; if c == 0 { panic!("bomb"); } e }); let it2 = [(); 0].iter(); let mut zip = it.zip(it2); catch_unwind(AssertUnwindSafe(|| { zip.next_back(); })) .unwrap_err(); assert!(zip.next().is_none()); assert_eq!(counter, 1); } #[test] </ins> fn test_double_ended_zip() { let xs = [1, 2, 3, 4, 5, 6]; let ys = [1, 2, 3, 7];


use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; <del> use crate::clean::{self, Attributes, AttributesExt, FakeDefId, GetDefId, ToSource}; </del> <ins> use crate::clean::{ self, Attributes, AttributesExt, FakeDefId, GetDefId, NestedAttributesExt, ToSource, Type, }; </ins> use crate::core::DocContext; use crate::formats::item_type::ItemType;


if trait_.def_id() == tcx.lang_items().deref_trait() { super::build_deref_target_impls(cx, &trait_items, ret); } <ins> // Return if the trait itself or any types of the generic parameters are doc(hidden). let mut stack: Vec<&Type> = trait_.iter().collect(); stack.push(&for_); while let Some(ty) = stack.pop() { if let Some(did) = ty.def_id() { if cx.tcx.get_attrs(did).lists(sym::doc).has_word(sym::hidden) { return; } } if let Some(generics) = ty.generics() { stack.extend(generics); } } </ins> if let Some(trait_did) = trait_.def_id() { record_extern_trait(cx, trait_did); }


<ins> #[doc(hidden)] pub enum HiddenType {} #[doc(hidden)] pub trait HiddenTrait {} </ins>


<ins> // Issue #86448: test for cross-crate `doc(hidden)` #![crate_name = "foo"] // aux-build:cross-crate-hidden-impl-parameter.rs extern crate cross_crate_hidden_impl_parameter; pub use ::cross_crate_hidden_impl_parameter::{HiddenType, HiddenTrait}; // OK, not re-exported pub enum MyLibType {} // @!has foo/enum.MyLibType.html '//*[@id="impl-From%3CHiddenType%3E"]' 'impl From<HiddenType> for MyLibType' impl From<HiddenType> for MyLibType { fn from(it: HiddenType) -> MyLibType { match it {} } } pub struct T<T>(T); // @!has foo/enum.MyLibType.html '//*[@id="impl-From%3CT%3CT%3CT%3CT%3CHiddenType%3E%3E%3E%3E%3E"]' 'impl From<T<T<T<T<HiddenType>>>>> for MyLibType' impl From<T<T<T<T<HiddenType>>>>> for MyLibType { fn from(it: T<T<T<T<HiddenType>>>>) -> MyLibType { todo!() } } // @!has foo/enum.MyLibType.html '//*[@id="impl-HiddenTrait"]' 'impl HiddenTrait for MyLibType' impl HiddenTrait for MyLibType {} // @!has foo/struct.T.html '//*[@id="impl-From%3CMyLibType%3E"]' 'impl From<MyLibType> for T<T<T<T<HiddenType>>>>' impl From<MyLibType> for T<T<T<T<HiddenType>>>> { fn from(it: MyLibType) -> T<T<T<T<HiddenType>>>> { match it {} } } </ins>


<ins> // test for `doc(hidden)` with impl parameters in the same crate. #![crate_name = "foo"] #[doc(hidden)] pub enum HiddenType {} #[doc(hidden)] pub trait HiddenTrait {} pub enum MyLibType {} // @!has foo/enum.MyLibType.html '//*[@id="impl-From%3CHiddenType%3E"]' 'impl From<HiddenType> for MyLibType' impl From<HiddenType> for MyLibType { fn from(it: HiddenType) -> MyLibType { match it {} } } pub struct T<T>(T); // @!has foo/enum.MyLibType.html '//*[@id="impl-From%3CT%3CT%3CT%3CT%3CHiddenType%3E%3E%3E%3E%3E"]' 'impl From<T<T<T<T<HiddenType>>>>> for MyLibType' impl From<T<T<T<T<HiddenType>>>>> for MyLibType { fn from(it: T<T<T<T<HiddenType>>>>) -> MyLibType { todo!() } } // @!has foo/enum.MyLibType.html '//*[@id="impl-HiddenTrait"]' 'impl HiddenTrait for MyLibType' impl HiddenTrait for MyLibType {} // @!has foo/struct.T.html '//*[@id="impl-From%3CMyLibType%3E"]' 'impl From<MyLibType> for T<T<T<T<HiddenType>>>>' impl From<MyLibType> for T<T<T<T<HiddenType>>>> { fn from(it: MyLibType) -> T<T<T<T<HiddenType>>>> { match it {} } } </ins>


<ins> #![feature(generic_const_exprs, array_map)] #![allow(incomplete_features)] pub struct ConstCheck<const CHECK: bool>; pub trait True {} impl True for ConstCheck<true> {} pub trait OrdesDec { type Newlen; type Output; fn pop(self) -> (Self::Newlen, Self::Output); } impl<T, const N: usize> OrdesDec for [T; N] where ConstCheck<{N > 1}>: True, [T; N - 1]: Sized, { type Newlen = [T; N - 1]; type Output = T; fn pop(self) -> (Self::Newlen, Self::Output) { let mut iter = IntoIter::new(self); //~^ ERROR: failed to resolve: use of undeclared type `IntoIter` let end = iter.next_back().unwrap(); let new = [(); N - 1].map(move |()| iter.next().unwrap()); (new, end) } } fn main() {} </ins>


<ins> error[E0433]: failed to resolve: use of undeclared type `IntoIter` --> $DIR/issue-82956.rs:25:24 | LL |         let mut iter = IntoIter::new(self); |                        ^^^^^^^^ not found in this scope | help: consider importing one of these items | LL | use std::array::IntoIter; | LL | use std::collections::binary_heap::IntoIter; | LL | use std::collections::btree_map::IntoIter; | LL | use std::collections::btree_set::IntoIter; | and 8 other candidates error: aborting due to previous error For more information about this error, try `rustc --explain E0433`. </ins>


<ins> #![allow(incomplete_features)] #![feature(generic_const_exprs)] trait Bar<const N: usize> {} trait Foo<'a> { const N: usize; type Baz: Bar<{ Self::N }>; //~^ ERROR: unconstrained generic constant } fn main() {} </ins>


<ins> error: unconstrained generic constant --> $DIR/issue-84659.rs:8:15 | LL |     type Baz: Bar<{ Self::N }>; |               ^^^^^^^^^^^^^^^^ | = help: try adding a `where` bound using this expression: `where [(); { Self::N }]:` error: aborting due to previous error </ins>


<ins> #![feature(generic_const_exprs)] #![allow(incomplete_features)] pub trait X { const Y: usize; } fn z<T>(t: T) where T: X, [(); T::Y]: , { } fn unit_literals() { z(" "); //~^ ERROR: the trait bound `&str: X` is not satisfied } fn main() {} </ins>


<ins> error[E0277]: the trait bound `&str: X` is not satisfied --> $DIR/issue-86530.rs:16:7 | LL |     z(" "); |       ^^^ the trait `X` is not implemented for `&str` | note: required by a bound in `z` --> $DIR/issue-86530.rs:10:8 | LL | fn z<T>(t: T) |    - required by a bound in this LL | where LL |     T: X, |        ^ required by this bound in `z` error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. </ins>


<ins> // run-pass #![feature(adt_const_params, generic_const_exprs)] #![allow(incomplete_features)] pub trait Foo { const ASSOC_C: usize; fn foo() where [(); Self::ASSOC_C]:; } struct Bar<const N: &'static ()>; impl<const N: &'static ()> Foo for Bar<N> { const ASSOC_C: usize = 3; fn foo() where [u8; Self::ASSOC_C]: { let _: [u8; Self::ASSOC_C] = loop {}; } } fn main() {} </ins>