pub async fn mut_self(mut self, mut first: usize) {} } <ins> pub trait Pattern<'a> {} </ins> pub trait Trait<const N: usize> {} // @has async_fn/fn.const_generics.html // @has - '//pre[@class="rust fn"]' 'pub async fn const_generics<const N: usize>(_: impl Trait<N>)' pub async fn const_generics<const N: usize>(_: impl Trait<N>) {} <ins> // test that elided lifetimes are properly elided and not displayed as `'_` // regression test for #63037 // @has async_fn/fn.elided.html // @has - '//pre[@class="rust fn"]' 'pub async fn elided(foo: &str) -> &str' pub async fn elided(foo: &str) -> &str {} // This should really be shown as written, but for implementation reasons it's difficult. // See `impl Clean for TyKind::Rptr`. // @has async_fn/fn.user_elided.html // @has - '//pre[@class="rust fn"]' 'pub async fn user_elided(foo: &str) -> &str' pub async fn user_elided(foo: &'_ str) -> &str {} // @has async_fn/fn.static_trait.html // @has - '//pre[@class="rust fn"]' 'pub async fn static_trait(foo: &str) -> Box<dyn Bar>' pub async fn static_trait(foo: &str) -> Box<dyn Bar> {} // @has async_fn/fn.lifetime_for_trait.html // @has - '//pre[@class="rust fn"]' "pub async fn lifetime_for_trait(foo: &str) -> Box<dyn Bar + '_>" pub async fn lifetime_for_trait(foo: &str) -> Box<dyn Bar + '_> {} // @has async_fn/fn.elided_in_input_trait.html // @has - '//pre[@class="rust fn"]' "pub async fn elided_in_input_trait(t: impl Pattern<'_>)" pub async fn elided_in_input_trait(t: impl Pattern<'_>) {} struct AsyncFdReadyGuard<'a, T> { x: &'a T } impl Foo { // @has async_fn/struct.Foo.html // @has - '//h4[@class="method"]' 'pub async fn complicated_lifetimes( &self, context: &impl Bar) -> impl Iterator<Item = &usize>' pub async fn complicated_lifetimes(&self, context: &impl Bar) -> impl Iterator<Item = &usize> {} // taken from `tokio` as an example of a method that was particularly bad before // @has - '//h4[@class="method"]' "pub async fn readable<T>(&self) -> Result<AsyncFdReadyGuard<'_, T>, ()>" pub async fn readable<T>(&self) -> Result<AsyncFdReadyGuard<'_, T>, ()> {} // @has - '//h4[@class="method"]' "pub async fn mut_self(&mut self)" pub async fn mut_self(&mut self) {} } // test named lifetimes, just in case // @has async_fn/fn.named.html // @has - '//pre[@class="rust fn"]' "pub async fn named<'a, 'b>(foo: &'a str) -> &'b str" pub async fn named<'a, 'b>(foo: &'a str) -> &'b str {} // @has async_fn/fn.named_trait.html // @has - '//pre[@class="rust fn"]' "pub async fn named_trait<'a, 'b>(foo: impl Pattern<'a>) -> impl Pattern<'b>" pub async fn named_trait<'a, 'b>(foo: impl Pattern<'a>) -> impl Pattern<'b> {} </ins>


pub(super) fn recover_parens_around_for_head( &mut self, pat: P<Pat>, <del> expr: &Expr, </del> begin_paren: Option<Span>, ) -> P<Pat> { match (&self.token.kind, begin_paren) { (token::CloseDelim(token::Paren), Some(begin_par_sp)) => { self.bump(); <del> let pat_str = self // Remove the `(` from the span of the pattern: .span_to_snippet(pat.span.trim_start(begin_par_sp).unwrap()) .unwrap_or_else(|_| pprust::pat_to_string(&pat)); self.struct_span_err(self.prev_token.span, "unexpected closing `)`") .span_label(begin_par_sp, "opening `(`") .span_suggestion( begin_par_sp.to(self.prev_token.span), "remove parenthesis in `for` loop", format!("{} in {}", pat_str, pprust::expr_to_string(&expr)), // With e.g. `for (x) in y)` this would replace `(x) in y)` // with `x) in y)` which is syntactically invalid. // However, this is prevented before we get here. Applicability::MachineApplicable, ) .emit(); </del> <ins> self.struct_span_err( MultiSpan::from_spans(vec![begin_par_sp, self.prev_token.span]), "unexpected parenthesis surrounding `for` loop head", ) .multipart_suggestion( "remove parenthesis in `for` loop", vec![(begin_par_sp, String::new()), (self.prev_token.span, String::new())], // With e.g. `for (x) in y)` this would replace `(x) in y)` // with `x) in y)` which is syntactically invalid. // However, this is prevented before we get here. Applicability::MachineApplicable, ) .emit(); </ins> // Unwrap `(pat)` into `pat` to avoid the `unused_parens` lint. pat.and_then(|pat| match pat.kind {


self.check_for_for_in_in_typo(self.prev_token.span); let expr = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?; <del> let pat = self.recover_parens_around_for_head(pat, &expr, begin_paren); </del> <ins> let pat = self.recover_parens_around_for_head(pat, begin_paren); </ins> let (iattrs, loop_block) = self.parse_inner_attrs_and_block()?; attrs.extend(iattrs);


for ( elem in vec ) { //~^ ERROR expected one of `)`, `,`, `@`, or `|`, found keyword `in` <del> //~| ERROR unexpected closing `)` </del> <ins> //~| ERROR unexpected parenthesis surrounding `for` loop head </ins> const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types } }


LL |     for ( elem in vec ) { |                ^^ expected one of `)`, `,`, `@`, or `|` <del> error: unexpected closing `)` --> $DIR/recover-for-loop-parens-around-head.rs:10:23 </del> <ins> error: unexpected parenthesis surrounding `for` loop head --> $DIR/recover-for-loop-parens-around-head.rs:10:9 </ins> | LL |     for ( elem in vec ) { <del> |         --------------^ |         | |         opening `(` |         help: remove parenthesis in `for` loop: `elem in vec` </del> <ins> |         ^             ^ | help: remove parenthesis in `for` loop | LL -     for ( elem in vec ) { LL +     for  elem in vec  { | </ins> error[E0308]: mismatched types --> $DIR/recover-for-loop-parens-around-head.rs:13:38


kind_name = "variant"; } None => { <del> let resolved_expected = fcx.infcx().ty_to_str(fcx.infcx().resolve_type_vars_if_possible(expected)); fcx.infcx().type_error_message_str(pat.span, |actual| { </del> <ins> fcx.infcx().type_error_message_str_with_expected(pat.span, |expected, actual| { expected.map_default(~"", |&e| { </ins> fmt!("mismatched types: expected `%s` but found %s", <del> resolved_expected, actual)}, ~"a structure pattern", </del> <ins> e, actual)})}, Some(expected), ~"a structure pattern", </ins> None); fcx.write_error(pat.id); kind_name = "[error]";


kind_name = "structure"; } _ => { <del> let resolved_expected = fcx.infcx().ty_to_str(fcx.infcx().resolve_type_vars_if_possible(expected)); fcx.infcx().type_error_message_str(pat.span, |actual| { </del> <ins> fcx.infcx().type_error_message_str_with_expected(pat.span, |expected, actual| { expected.map_default(~"", |&e| { </ins> fmt!("mismatched types: expected `%s` but found %s", <del> resolved_expected, actual)}, ~"an enum or structure pattern", </del> <ins> e, actual)})}, Some(expected), ~"an enum or structure pattern", </ins> None); fcx.write_error(pat.id); kind_name = "[error]";


for elts.each |elt| { check_pat(pcx, *elt, ty::mk_err()); } <del> let actual = ty::mk_tup(tcx, elts.map(|pat_var| { fcx.node_ty(pat_var.id) })); </del> // use terr_tuple_size if both types are tuples let type_error = match s { ty::ty_tup(ref ex_elts) =>


found: e_count}), _ => ty::terr_mismatch }; <del> fcx.infcx().report_mismatched_types(pat.span, expected, actual, &type_error); </del> <ins> fcx.infcx().type_error_message_str_with_expected(pat.span, |expected, actual| { expected.map_default(~"", |&e| { fmt!("mismatched types: expected `%s` but found %s", e, actual)})}, Some(expected), ~"tuple", Some(&type_error)); </ins> fcx.write_error(pat.id); } }


for after.each |&elt| { check_pat(pcx, elt, ty::mk_err()); } <del> let resolved_expected = fcx.infcx().ty_to_str(fcx.infcx().resolve_type_vars_if_possible(expected)); fcx.infcx().type_error_message_str(pat.span, |actual| { fmt!("mismatched types: expected `%s` but found %s", resolved_expected, actual)}, ~"a vector pattern", None); </del> <ins> fcx.infcx().type_error_message_str_with_expected( pat.span, |expected, actual| { expected.map_default(~"", |&e| { fmt!("mismatched types: expected `%s` but found %s", e, actual)})}, Some(expected), ~"a vector pattern", None); </ins> fcx.write_error(pat.id); return; }


} _ => { check_pat(pcx, inner, ty::mk_err()); <del> let resolved_expected = fcx.infcx().ty_to_str(fcx.infcx().resolve_type_vars_if_possible(expected)); fcx.infcx().type_error_message_str(span, |actual| { fmt!("mismatched types: expected `%s` but found %s", resolved_expected, actual)}, fmt!("%s pattern", match pointer_kind { Managed => "an @-box", Owned => "a ~-box", Borrowed => "an &-pointer" }), None); </del> <ins> fcx.infcx().type_error_message_str_with_expected( span, |expected, actual| { expected.map_default(~"", |&e| { fmt!("mismatched types: expected `%s` but found %s", e, actual)})}, Some(expected), fmt!("%s pattern", match pointer_kind { Managed => "an @-box", Owned => "a ~-box", Borrowed => "an &-pointer" }), None); </ins> fcx.write_error(pat_id); } }


} } <ins> fn type_error_message_str(@mut self, sp: span, mk_msg: &fn(Option<~str>, ~str) -> ~str, actual_ty: ~str, err: Option<&ty::type_err>) { self.type_error_message_str_with_expected(sp, mk_msg, None, actual_ty, err) } fn type_error_message_str_with_expected(@mut self, sp: span, mk_msg: &fn(Option<~str>, ~str) -> ~str, expected_ty: Option<ty::t>, actual_ty: ~str, err: Option<&ty::type_err>) { debug!("hi! expected_ty = %?, actual_ty = %s", expected_ty, actual_ty); </ins> <del> fn type_error_message_str(@mut self, sp: span, mk_msg: &fn(~str) -> ~str, actual_ty: ~str, err: Option<&ty::type_err>) { </del> let error_str = err.map_default(~"", |t_err| fmt!(" (%s)", ty::type_err_to_str(self.tcx, *t_err))); <del> self.tcx.sess.span_err(sp, fmt!("%s%s", mk_msg(actual_ty), error_str)); for err.each |err| { ty::note_and_explain_type_err(self.tcx, *err) </del> <ins> let resolved_expected = expected_ty.map(|&e_ty| { self.resolve_type_vars_if_possible(e_ty) }); if !resolved_expected.map_default(false, |&e| { ty::type_is_error(e) }) { match resolved_expected { None => self.tcx.sess.span_err(sp, fmt!("%s%s", mk_msg(None, actual_ty), error_str)), Some(e) => { self.tcx.sess.span_err(sp, fmt!("%s%s", mk_msg(Some(self.ty_to_str(e)), actual_ty), error_str)); } } for err.each |err| { ty::note_and_explain_type_err(self.tcx, *err) } </ins> } } <del> fn type_error_message(@mut self, sp: span, mk_msg: &fn(~str) -> ~str, actual_ty: ty::t, err: Option<&ty::type_err>) { </del> <ins> fn type_error_message(@mut self, sp: span, mk_msg: &fn(~str) -> ~str, actual_ty: ty::t, err: Option<&ty::type_err>) { </ins> let actual_ty = self.resolve_type_vars_if_possible(actual_ty); // Don't report an error if actual type is ty_err.


return; } <del> self.type_error_message_str(sp, mk_msg, self.ty_to_str(actual_ty), err); </del> <ins> self.type_error_message_str(sp, |_e, a| { mk_msg(a) }, self.ty_to_str(actual_ty), err); </ins> } fn report_mismatched_types(@mut self, sp: span, e: ty::t, a: ty::t,


} match (true, false) { <del> (true, false, false) => () //~ ERROR mismatched types: expected `(bool,bool)` but found `(bool,bool,bool)` (expected a tuple with 2 elements but found one with 3 elements) </del> <ins> (true, false, false) => () //~ ERROR mismatched types: expected `(bool,bool)` but found tuple (expected a tuple with 2 elements but found one with 3 elements) </ins> } match (true, false) {


<ins> // Copyright 2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. fn main() { let (x, y) = (); //~ ERROR expected `()` but found tuple (types differ) return x; } </ins>  No newline at end of file


) -> Bx::Value { let is_float = input_ty.is_floating_point(); let is_signed = input_ty.is_signed(); <del> let is_unit = input_ty.is_unit(); </del> match op { mir::BinOp::Add => if is_float { bx.fadd(lhs, rhs)


mir::BinOp::Shl => common::build_unchecked_lshift(bx, lhs, rhs), mir::BinOp::Shr => common::build_unchecked_rshift(bx, input_ty, lhs, rhs), mir::BinOp::Ne | mir::BinOp::Lt | mir::BinOp::Gt | <del> mir::BinOp::Eq | mir::BinOp::Le | mir::BinOp::Ge => if is_unit { bx.cx().const_bool(match op { mir::BinOp::Ne | mir::BinOp::Lt | mir::BinOp::Gt => false, mir::BinOp::Eq | mir::BinOp::Le | mir::BinOp::Ge => true, _ => unreachable!() }) } else if is_float { </del> <ins> mir::BinOp::Eq | mir::BinOp::Le | mir::BinOp::Ge => if is_float { </ins> bx.fcmp( base::bin_op_to_fcmp_predicate(op.to_hir_binop()), lhs, rhs


<del> Subproject commit 4f6f264c305ea30f1de90ad0c2f341e84d972b2e </del> <ins> Subproject commit d77fe6c63ca4c50b207a1161def90c9e57368d5b </ins>


self.is_keyword_ahead(1, &[ kw::Impl, kw::Const, <ins> kw::Async, </ins> kw::Fn, kw::Unsafe, kw::Extern,


<ins> // Ensure that `default async fn` will parse. // See issue #63716 for details. // check-pass // edition:2018 #![feature(specialization)] fn main() {} #[cfg(FALSE)] impl Foo for Bar { default async fn baz() {} } </ins>


/// [`len`]: #method.len /// /// Note: This example shows the internals of `&str`. `unsafe` should not be <del> /// used to get a string slice under normal circumstances. Use `as_slice` </del> <ins> /// used to get a string slice under normal circumstances. Use `as_str` </ins> /// instead. #[stable(feature = "rust1", since = "1.0.0")] mod prim_str { }


<ins> use rustc_data_structures::fx::FxHashMap; </ins> use syntax_pos::Span; use crate::print::pprust::token_to_string;


unmatched_braces: Vec::new(), matching_delim_spans: Vec::new(), last_unclosed_found_span: None, <ins> last_delim_empty_block_spans: FxHashMap::default() </ins> }; let res = tt_reader.parse_all_token_trees(); (res, tt_reader.unmatched_braces)


/// Used only for error recovery when arriving to EOF with mismatched braces. matching_delim_spans: Vec<(token::DelimToken, Span, Span)>, last_unclosed_found_span: Option<Span>, <ins> last_delim_empty_block_spans: FxHashMap<token::DelimToken, Span> </ins> } impl<'a> TokenTreesReader<'a> {


// Correct delimiter. token::CloseDelim(d) if d == delim => { let (open_brace, open_brace_span) = self.open_braces.pop().unwrap(); <ins> let close_brace_span = self.token.span; if tts.is_empty() { let empty_block_span = open_brace_span.to(close_brace_span); self.last_delim_empty_block_spans.insert(delim, empty_block_span); } </ins> if self.open_braces.len() == 0 { // Clear up these spans to avoid suggesting them as we've found // properly matched delimiters so far for an entire block. self.matching_delim_spans.clear(); } else { self.matching_delim_spans.push( <del> (open_brace, open_brace_span, self.token.span), </del> <ins> (open_brace, open_brace_span, close_brace_span), </ins> ); } // Parse the close delimiter.


tts.into() ).into()) }, <del> token::CloseDelim(_) => { </del> <ins> token::CloseDelim(delim) => { </ins> // An unexpected closing delimiter (i.e., there is no // matching opening delimiter). let token_str = token_to_string(&self.token); let msg = format!("unexpected close delimiter: `{}`", token_str); let mut err = self.string_reader.sess.span_diagnostic .struct_span_err(self.token.span, &msg); <ins> if let Some(span) = self.last_delim_empty_block_spans.remove(&delim) { err.span_label( span, "this block is empty, you might have not meant to close it" ); } </ins> err.span_label(self.token.span, "unexpected close delimiter"); Err(err) },


} /// A delimiter token. <del> #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] </del> <ins> #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] </ins> pub enum DelimToken { /// A round parenthesis (i.e., `(` or `)`). Paren,


<ins> fn main() { } let _ = (); } //~ ERROR unexpected close delimiter </ins>


<ins> error: unexpected close delimiter: `}` --> $DIR/mismatched-delim-brace-empty-block.rs:5:1 | LL |   fn main() { |  ___________- LL | | LL | | } | |_- this block is empty, you might have not meant to close it LL |       let _ = (); LL |   } |   ^ unexpected close delimiter error: aborting due to previous error </ins>


<ins> // This test ensures that `--` (double-hyphen) is correctly converted into `–` (dash). #![crate_name = "foo"] // @has 'foo/index.html' '//*[@class="desc docblock-short"]' '–' // @has 'foo/struct.Bar.html' '//*[@class="docblock"]' '–' /// -- pub struct Bar; </ins>


use crate::hir::def_id::DefId; use crate::hir; use crate::ty::TyCtxt; <del> use syntax_pos::symbol::{sym, Symbol}; </del> <ins> use syntax_pos::symbol::Symbol; </ins> use crate::hir::map::blocks::FnLikeNode; use syntax::attr;


self.is_const_fn_raw(def_id) && match self.is_unstable_const_fn(def_id) { Some(feature_name) => { // has a `rustc_const_unstable` attribute, check whether the user enabled the <del> // corresponding feature gate, const_constructor is not a lib feature, so has // to be checked separately. </del> <ins> // corresponding feature gate. </ins> self.features() .declared_lib_features .iter() .any(|&(sym, _)| sym == feature_name) <del> || (feature_name == sym::const_constructor && self.features().const_constructor) </del> }, // functions without const stability are either stable user written // const fn or the user is using feature gates and we thus don't


/// Whether the `def_id` is an unstable const fn and what feature gate is necessary to enable it pub fn is_unstable_const_fn(self, def_id: DefId) -> Option<Symbol> { <del> if self.is_constructor(def_id) { Some(sym::const_constructor) } else if self.is_const_fn_raw(def_id) { </del> <ins> if self.is_const_fn_raw(def_id) { </ins> self.lookup_stability(def_id)?.const_stability } else { None


(accepted, macros_in_extern, "1.40.0", Some(49476), None), /// Allows future-proofing enums/structs with the `#[non_exhaustive]` attribute (RFC 2008). (accepted, non_exhaustive, "1.40.0", Some(44109), None), <ins> /// Allows calling constructor functions in `const fn`. (accepted, const_constructor, "1.40.0", Some(61456), None), </ins> // ------------------------------------------------------------------------- // feature-group-end: accepted features


/// Allows the user of associated type bounds. (active, associated_type_bounds, "1.34.0", Some(52662), None), <del> /// Allows calling constructor functions in `const fn`. (active, const_constructor, "1.37.0", Some(61456), None), </del> /// Allows `if/while p && let q = r && ...` chains. (active, let_chains, "1.37.0", Some(53667), None),


#![cfg_attr(const_fn, feature(const_fn))] <del> #![feature(const_constructor)] </del> // Ctor(..) is transformed to Ctor { 0: ... } in HAIR lowering, so directly // calling constructors doesn't require them to be const.


<ins> // revisions: min_const_fn const_fn // run-pass #![cfg_attr(const_fn, feature(const_fn))] trait ConstDefault { const DEFAULT: Self; } #[derive(PartialEq)] enum E { V(i32), W(usize), } impl ConstDefault for E { const DEFAULT: Self = Self::V(23); } impl ConstDefault for Option<i32> { const DEFAULT: Self = Self::Some(23); } impl E { const NON_DEFAULT: Self = Self::W(12); const fn local_fn() -> Self { Self::V(23) } } const fn explicit_qpath() -> E { let _x = <Option<usize>>::Some(23); <E>::W(12) } fn main() { assert!(E::DEFAULT == E::local_fn()); assert!(Option::DEFAULT == Some(23)); assert!(E::NON_DEFAULT == explicit_qpath()); } </ins>


<del> error: `std::prelude::v1::Some` is not yet stable as a const fn --> $DIR/feature-gate-const_constructor.rs:9:37 | LL | const EXTERNAL_CONST: Option<i32> = {Some}(1); |                                     ^^^^^^^^^ | = help: add `#![feature(const_constructor)]` to the crate attributes to enable error: `E::V` is not yet stable as a const fn --> $DIR/feature-gate-const_constructor.rs:12:24 | LL | const LOCAL_CONST: E = {E::V}(1); |                        ^^^^^^^^^ | = help: add `#![feature(const_constructor)]` to the crate attributes to enable error: `std::prelude::v1::Some` is not yet stable as a const fn --> $DIR/feature-gate-const_constructor.rs:17:13 | LL |     let _ = {Some}(1); |             ^^^^^^^^^ | = help: add `#![feature(const_constructor)]` to the crate attributes to enable error: `E::V` is not yet stable as a const fn --> $DIR/feature-gate-const_constructor.rs:23:13 | LL |     let _ = {E::V}(1); |             ^^^^^^^^^ | = help: add `#![feature(const_constructor)]` to the crate attributes to enable error: aborting due to 4 previous errors </del>


<del> // revisions: min_const_fn const_fn #![cfg_attr(const_fn, feature(const_fn))] enum E { V(i32), } const EXTERNAL_CONST: Option<i32> = {Some}(1); //[min_const_fn]~^ ERROR is not yet stable as a const fn //[const_fn]~^^ ERROR is not yet stable as a const fn const LOCAL_CONST: E = {E::V}(1); //[min_const_fn]~^ ERROR is not yet stable as a const fn //[const_fn]~^^ ERROR is not yet stable as a const fn const fn external_fn() { let _ = {Some}(1); //[min_const_fn]~^ ERROR is not yet stable as a const fn //[const_fn]~^^ ERROR is not yet stable as a const fn } const fn local_fn() { let _ = {E::V}(1); //[min_const_fn]~^ ERROR is not yet stable as a const fn //[const_fn]~^^ ERROR is not yet stable as a const fn } fn main() {} </del>


/// Free-form case. Only for errors that are never caught! Unsupported(String), <del> /// FIXME(#64506) Error used to work around accessing projections of /// uninhabited types. UninhabitedValue, </del> // -- Everything below is not categorized yet -- FunctionAbiMismatch(Abi, Abi), FunctionArgMismatch(Ty<'tcx>, Ty<'tcx>),


not a power of two"), Unsupported(ref msg) => write!(f, "{}", msg), <del> UninhabitedValue => write!(f, "tried to use an uninhabited value"), </del> } } }


}); (present_variants.next(), present_variants.next()) }; <del> if present_first.is_none() { </del> <ins> let present_first = match present_first { present_first @ Some(_) => present_first, </ins> // Uninhabited because it has no variants, or only absent ones. <del> return tcx.layout_raw(param_env.and(tcx.types.never)); } </del> <ins> None if def.is_enum() => return tcx.layout_raw(param_env.and(tcx.types.never)), // if it's a struct, still compute a layout so that we can still compute the // field offsets None => Some(VariantIdx::new(0)), }; </ins> let is_struct = !def.is_enum() || // Only one variant is present.


use rustc::mir::interpret::truncate; use rustc::ty::{self, Ty}; use rustc::ty::layout::{ <del> self, Size, Abi, Align, LayoutOf, TyLayout, HasDataLayout, VariantIdx, PrimitiveExt </del> <ins> self, Size, Align, LayoutOf, TyLayout, HasDataLayout, VariantIdx, PrimitiveExt </ins> }; use rustc::ty::TypeFoldable;


layout::FieldPlacement::Array { stride, .. } => { let len = base.len(self)?; if field >= len { <del> // This can be violated because this runs during promotion on code where the // type system has not yet ensured that such things don't happen. </del> <ins> // This can be violated because the index (field) can be a runtime value // provided by the user. </ins> debug!("tried to access element {} of array/slice with length {}", field, len); throw_panic!(BoundsCheck { len, index: field }); } stride * field } layout::FieldPlacement::Union(count) => { <del> // FIXME(#64506) `UninhabitedValue` can be removed when this issue is resolved if base.layout.abi == Abi::Uninhabited { throw_unsup!(UninhabitedValue); } </del> assert!(field < count as u64, <del> "Tried to access field {} of union with {} fields", field, count); </del> <ins> "Tried to access field {} of union {:#?} with {} fields", field, base.layout, count); </ins> // Offset is always 0 Size::from_bytes(0) }


pub fn offset(&self, i: usize) -> Size { match *self { <del> FieldPlacement::Union(_) => Size::ZERO, </del> <ins> FieldPlacement::Union(count) => { assert!(i < count, "Tried to access field {} of union with {} fields", i, count); Size::ZERO }, </ins> FieldPlacement::Array { stride, count } => { let i = i as u64; assert!(i < count);


<ins> // check-pass #[derive(Copy, Clone)] pub struct ChildStdin { inner: AnonPipe, } #[derive(Copy, Clone)] enum AnonPipe {} const FOO: () = { union Foo { a: ChildStdin, b: (), } let x = unsafe { Foo { b: () }.a }; let x = &x.inner; }; fn main() {} </ins>


if let hir::ExprKind::Index(ref base, ref index) = e.kind { let mut tables = self.fcx.tables.borrow_mut(); <del> // All valid indexing looks like this; might encounter non-valid indexes at this point if let ty::Ref(_, base_ty, _) = tables.expr_ty_adjusted(&base).kind { let index_ty = tables.expr_ty_adjusted(&index); </del> <ins> // All valid indexing looks like this; might encounter non-valid indexes at this point. let base_ty = tables.expr_ty_adjusted_opt(&base).map(|t| &t.kind); if base_ty.is_none() { // When encountering `return [0][0]` outside of a `fn` body we can encounter a base // that isn't in the type table. We assume more relevant errors have already been // emitted, so we delay an ICE if none have. (#64638) self.tcx().sess.delay_span_bug(e.span, &format!("bad base: `{:?}`", base)); } if let Some(ty::Ref(_, base_ty, _)) = base_ty { let index_ty = tables.expr_ty_adjusted_opt(&index).unwrap_or_else(|| { // When encountering `return [0][0]` outside of a `fn` body we would attempt // to access an unexistend index. We assume that more relevant errors will // already have been emitted, so we only gate on this with an ICE if no // error has been emitted. (#64638) self.tcx().sess.delay_span_bug( e.span, &format!("bad index {:?} for base: `{:?}`", index, base), ); self.fcx.tcx.types.err }); </ins> let index_ty = self.fcx.resolve_vars_if_possible(&index_ty); if base_ty.builtin_index().is_some() && index_ty == self.fcx.tcx.types.usize {


<ins> enum Bug { V1 = return [0][0] //~ERROR return statement outside of function body } fn main() {} </ins>


<ins> error[E0572]: return statement outside of function body --> $DIR/issue-64620.rs:2:10 | LL |     V1 = return [0][0] |          ^^^^^^^^^^^^^ error: aborting due to previous error For more information about this error, try `rustc --explain E0572`. </ins>


// ignore it.  We can't put it on the struct header anyway. RegionKind::ReLateBound(..) => false, <ins> // This can appear in `where Self: ` bounds (#64855): // //     struct Bar<T>(<Self as Foo>::Type) where Self: ; //     struct Baz<'a>(&'a Self) where Self: ; RegionKind::ReEmpty => false, </ins> // These regions don't appear in types from type declarations: <del> RegionKind::ReEmpty | RegionKind::ReErased </del> <ins> RegionKind::ReErased </ins> | RegionKind::ReClosureBound(..) | RegionKind::ReScope(..) | RegionKind::ReVar(..)


<ins> // check-pass pub struct Bar<'a>(&'a Self) where Self: ; fn main() {} </ins>


<ins> pub trait Foo { type Type; } pub struct Bar<T>(<Self as Foo>::Type) where Self: ; //~^ ERROR the trait bound `Bar<T>: Foo` is not satisfied fn main() {} </ins>


<ins> error[E0277]: the trait bound `Bar<T>: Foo` is not satisfied --> $DIR/issue-64855.rs:5:19 | LL | pub struct Bar<T>(<Self as Foo>::Type) where Self: ; |                   ^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `Bar<T>` error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. </ins>


use syntax::feature_gate::{GateIssue, emit_feature_err}; use syntax::source_map::{DUMMY_SP, original_sp}; use syntax::symbol::{kw, sym}; <ins> use syntax::util::parser::ExprPrecedence; </ins> use std::cell::{Cell, RefCell, Ref, RefMut}; use std::collections::hash_map::Entry;


let max_len = receiver.rfind(".").unwrap(); format!("{}{}", &receiver[..max_len], method_call) } else { <del> format!("{}{}", receiver, method_call) </del> <ins> if expr.precedence().order() < ExprPrecedence::MethodCall.order() { format!("({}){}", receiver, method_call) } else { format!("{}{}", receiver, method_call) } </ins> }; Some(if is_struct_pat_shorthand_field { format!("{}: {}", receiver, sugg)


|                                               ^^^^^^^^^^ |                                               | |                                               expected struct `std::vec::Vec`, found reference <del> |                                               help: try using a conversion method: `&[1, 2, 3].to_vec()` </del> <ins> |                                               help: try using a conversion method: `(&[1, 2, 3]).to_vec()` </ins> | = note: expected type `std::vec::Vec<usize>` found type `&[{integer}; 3]`


|             ^^^^^ |             | |             cyclic type of infinite size <del> |             help: try using a conversion method: `box x.to_string()` </del> <ins> |             help: try using a conversion method: `(box x).to_string()` </ins> error[E0055]: reached the recursion limit while auto-dereferencing `Foo` --> $DIR/infinite-autoderef.rs:25:5


x //~ ERROR mismatched types } <ins> fn f() -> String { 1+2 //~ ERROR mismatched types } fn g() -> String { -2 //~ ERROR mismatched types } </ins> fn main() {}


= note: expected type `X<X<_, std::string::String>, _>` found type `X<X<_, {integer}>, _>` <del> error: aborting due to 6 previous errors </del> <ins> error[E0308]: mismatched types --> $DIR/abridged.rs:54:5 | LL | fn f() -> String { |           ------ expected `std::string::String` because of return type LL |     1+2 |     ^^^ |     | |     expected struct `std::string::String`, found integer |     help: try using a conversion method: `(1+2).to_string()` | = note: expected type `std::string::String` found type `{integer}` error[E0308]: mismatched types --> $DIR/abridged.rs:59:5 | LL | fn g() -> String { |           ------ expected `std::string::String` because of return type LL |     -2 |     ^^ |     | |     expected struct `std::string::String`, found integer |     help: try using a conversion method: `(-2).to_string()` | = note: expected type `std::string::String` found type `{integer}` error: aborting due to 8 previous errors </ins> For more information about this error, try `rustc --explain E0308`.


|         ^^^^^ |         | |         cyclic type of infinite size <del> |         help: try using a conversion method: `box g.to_string()` </del> <ins> |         help: try using a conversion method: `(box g).to_string()` </ins> error: aborting due to previous error


|         ^^^^^ |         | |         cyclic type of infinite size <del> |         help: try using a conversion method: `box f.to_string()` </del> <ins> |         help: try using a conversion method: `(box f).to_string()` </ins> error: aborting due to previous error


|         ^^^^^ |         | |         cyclic type of infinite size <del> |         help: try using a conversion method: `box f.to_string()` </del> <ins> |         help: try using a conversion method: `(box f).to_string()` </ins> error[E0308]: mismatched types --> $DIR/coerce-suggestions.rs:21:9


param_env: ty::ParamEnv<'tcx>, } <ins> impl<'tcx> TransferFunction<'_, '_, 'tcx> { /// Returns `true` if this borrow would allow mutation of the `borrowed_place`. fn borrow_allows_mutation( &self, kind: mir::BorrowKind, borrowed_place: &mir::Place<'tcx>, ) -> bool { let borrowed_ty = borrowed_place.ty(self.body, self.tcx).ty; // Zero-sized types cannot be mutated, since there is nothing inside to mutate. // // FIXME: For now, we only exempt arrays of length zero. We need to carefully // consider the effects before extending this to all ZSTs. if let ty::Array(_, len) = borrowed_ty.kind { if len.try_eval_usize(self.tcx, self.param_env) == Some(0) { return false; } } match kind { mir::BorrowKind::Mut { .. } => true, | mir::BorrowKind::Shared | mir::BorrowKind::Shallow | mir::BorrowKind::Unique => !borrowed_ty.is_freeze(self.tcx, self.param_env, DUMMY_SP), } } } </ins> impl<'tcx> Visitor<'tcx> for TransferFunction<'_, '_, 'tcx> { fn visit_rvalue( &mut self,


location: Location, ) { if let mir::Rvalue::Ref(_, kind, ref borrowed_place) = *rvalue { <del> let is_mut = match kind { mir::BorrowKind::Mut { .. } => true, | mir::BorrowKind::Shared | mir::BorrowKind::Shallow | mir::BorrowKind::Unique => { !borrowed_place .ty(self.body, self.tcx) .ty .is_freeze(self.tcx, self.param_env, DUMMY_SP) } }; if is_mut { </del> <ins> if self.borrow_allows_mutation(kind, borrowed_place) { </ins> match borrowed_place.base { mir::PlaceBase::Local(borrowed_local) if !borrowed_place.is_indirect() => self.trans.gen(borrowed_local),


item.tcx, item.body, item.def_id, <del> &[], </del> <ins> &item.tcx.get_attrs(item.def_id), </ins> &dead_unwinds, old_dataflow::IndirectlyMutableLocals::new(item.tcx, item.body, item.param_env), |_, local| old_dataflow::DebugFormatted::new(&local),


<ins> // Several variants of #64945. // This struct is not important, we just use it to put `T` and `'a` in scope for our associated // consts. struct Generic<'a, T>(std::marker::PhantomData<&'a T>); impl<'a, T: 'static> Generic<'a, T> { const EMPTY_SLICE: &'a [T] = { let x: &'a [T] = &[]; x }; const EMPTY_SLICE_REF: &'a &'static [T] = { let x: &'static [T] = &[]; &x //~^ ERROR `x` does not live long enough }; } static mut INTERIOR_MUT_AND_DROP: &'static [std::cell::RefCell<Vec<i32>>] = { let x: &[_] = &[]; x }; static mut INTERIOR_MUT_AND_DROP_REF: &'static &'static [std::cell::RefCell<Vec<i32>>] = { let x: &[_] = &[]; &x //~^ ERROR `x` does not live long enough }; fn main() {} </ins>


<ins> error[E0597]: `x` does not live long enough --> $DIR/generic-slice.rs:15:9 | LL | impl<'a, T: 'static> Generic<'a, T> { |      -- lifetime `'a` defined here ... LL |         &x |         ^^ |         | |         borrowed value does not live long enough |         using this value as a constant requires that `x` is borrowed for `'a` LL | LL |     }; |     - `x` dropped here while still borrowed error[E0597]: `x` does not live long enough --> $DIR/generic-slice.rs:27:5 | LL |     &x |     ^^ |     | |     borrowed value does not live long enough |     using this value as a static requires that `x` is borrowed for `'static` LL | LL | }; | - `x` dropped here while still borrowed error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0597`. </ins>


}); if (e.which === 38) { // up <del> if (!actives[currentTab].length || !actives[currentTab][0].previousElementSibling) { return; </del> <ins> if (e.ctrlKey) { // Going through result tabs. printTab(currentTab > 0 ? currentTab - 1 : 2); } else { if (!actives[currentTab].length || !actives[currentTab][0].previousElementSibling) { return; } addClass(actives[currentTab][0].previousElementSibling, "highlighted"); removeClass(actives[currentTab][0], "highlighted"); </ins> } <del> addClass(actives[currentTab][0].previousElementSibling, "highlighted"); removeClass(actives[currentTab][0], "highlighted"); </del> e.preventDefault(); } else if (e.which === 40) { // down <del> if (!actives[currentTab].length) { </del> <ins> if (e.ctrlKey) { // Going through result tabs. printTab(currentTab > 1 ? 0 : currentTab + 1); } else if (!actives[currentTab].length) { </ins> var results = document.getElementById("results").childNodes; if (results.length > 0) { var res = results[currentTab].getElementsByClassName("result");


document.location.href = actives[currentTab][0].getElementsByTagName("a")[0].href; } <del> } else if (e.which === 9) { // tab if (e.shiftKey) { printTab(currentTab > 0 ? currentTab - 1 : 2); } else { printTab(currentTab > 1 ? 0 : currentTab + 1); } e.preventDefault(); </del> } else if (e.which === 16) { // shift // Does nothing, it's just to avoid losing "focus" on the highlighted element. } else if (actives[currentTab].length > 0) {


["T", "Focus the theme picker menu"], ["↑", "Move up in search results"], ["↓", "Move down in search results"],  ["↹", "Switch tab"],   ["ctrl + ↑ / ↓", "Switch result tab"],  ["⏎", "Go to active search result"], ["+", "Expand all sections"], ["-", "Collapse all sections"],  ].map(x => "
" + x[0] + "

" + x[1] + "
").join("");   ].map(x => "
" + x[0].split(" ") .map((y, index) => (index & 1) === 0 ? "" + y + "" : y) .join("") + "

" + x[1] + "
").join("");  var div_shortcuts = document.createElement("div"); addClass(div_shortcuts, "shortcuts"); div_shortcuts.innerHTML = "
Keyboard Shortcuts

" + shortcuts + "

";


cc @{}, do you think you would have time to do the follow-up work? If so, that would be great! <del> cc @{}, the PR reviewer, and @rust-lang/compiler -- nominating for prioritization. </del> <ins> cc @{}, the PR reviewer, and nominating for compiler team prioritization. </ins> ''').format( relevant_pr_number, tool, status_description,


declare_lint! { pub CONST_ERR, Deny, <del> "constant evaluation detected erroneous expression" </del> <ins> "constant evaluation detected erroneous expression", report_in_external_macro: true </ins> } declare_lint! {


<ins> #![feature(allow_internal_unstable)] // Macro to help ensure CONST_ERR lint errors // are not silenced in external macros. // https://github.com/rust-lang/rust/issues/65300 #[macro_export] #[allow_internal_unstable(type_ascription)] macro_rules! static_assert { ($test:expr) => { #[allow(dead_code)] const _: () = [()][!($test: bool) as usize]; } } </ins>


<ins> // edition:2018 // aux-build:external_macro.rs // Ensure that CONST_ERR lint errors // are not silenced in external macros. // https://github.com/rust-lang/rust/issues/65300 extern crate external_macro; use external_macro::static_assert; fn main() { static_assert!(2 + 2 == 5); //~ ERROR } </ins>


<ins> error: any use of this value will cause an error --> $DIR/const-external-macro-const-err.rs:12:5 | LL |     static_assert!(2 + 2 == 5); |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the len is 1 but the index is 1 | = note: `#[deny(const_err)]` on by default = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: aborting due to previous error </ins>


<del> Subproject commit 5cb983338e924ec85898880d60e65f2a1291b7be </del> <ins> Subproject commit 52cebb1f8f8789b97d243c07bf4c961ca0017f7b </ins>


#[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for RangeFull { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { <del> fmt::Debug::fmt("..", fmt) </del> <ins> write!(fmt, "..") </ins> } }


<del> Subproject commit 941968db2fd9c85788a4f971c8e425d46b4cb734 </del> <ins> Subproject commit 75a5f9236c689a547fe207a10854f0775bce7937 </ins>


"regex-syntax", "semver", "serde", <del> "smallvec 0.6.10", </del> <ins> "smallvec 1.0.0", </ins> "toml", "unicode-normalization", "url 2.1.0",


let host_libs = builder .stage_out(compiler, Mode::ToolRustc) .join(builder.cargo_dir()); <ins> let target_libs = builder .stage_out(compiler, Mode::ToolRustc) .join(&self.host) .join(builder.cargo_dir()); </ins> cargo.env("HOST_LIBS", host_libs); <ins> cargo.env("TARGET_LIBS", target_libs); </ins> // clippy tests need to find the driver cargo.env("CLIPPY_DRIVER_PATH", clippy);


<del> Subproject commit c8e3cfbdd997839c771ca32c7ac860fe95149a04 </del> <ins> Subproject commit 3abdd2f1ced4cf3a44c7de88c5e39b3bb5037c4d </ins>


let result = match (&desc.should_panic, task_result) { (&ShouldPanic::No, Ok(())) | (&ShouldPanic::Yes, Err(_)) => TestResult::TrOk, (&ShouldPanic::YesWithMessage(msg), Err(ref err)) => { <del> if err </del> <ins> let maybe_panic_str = err </ins> .downcast_ref::<String>() .map(|e| &**e) <del> .or_else(|| err.downcast_ref::<&'static str>().map(|e| *e)) .map(|e| e.contains(msg)) .unwrap_or(false) { </del> <ins> .or_else(|| err.downcast_ref::<&'static str>().map(|e| *e)); if maybe_panic_str.map(|e| e.contains(msg)).unwrap_or(false) { </ins> TestResult::TrOk <ins> } else if desc.allow_fail { TestResult::TrAllowedFail } else if let Some(panic_str) = maybe_panic_str { TestResult::TrFailedMsg(format!( r#"panic did not contain expected string panic message: `{:?}`, expected substring: `{:?}`"#, panic_str, msg )) </ins> } else { <del> if desc.allow_fail { TestResult::TrAllowedFail } else { TestResult::TrFailedMsg( format!("panic did not include expected string '{}'", msg) ) } </del> <ins> TestResult::TrFailedMsg(format!( r#"expected panic with string value, found non-string value: `{:?}` expected substring: `{:?}`"#, (**err).type_id(), msg )) </ins> } } (&ShouldPanic::Yes, Ok(())) => {


// TestType, TrFailedMsg, TrIgnored, TrOk, }, }; <ins> use std::any::TypeId; </ins> use std::sync::mpsc::channel; use std::time::Duration;


let (tx, rx) = channel(); run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No); let result = rx.recv().unwrap().result; <del> assert!(result != TrOk); </del> <ins> assert_ne!(result, TrOk); </ins> } #[test]


let (tx, rx) = channel(); run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No); let result = rx.recv().unwrap().result; <del> assert!(result == TrIgnored); </del> <ins> assert_eq!(result, TrIgnored); </ins> } // FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251)


let (tx, rx) = channel(); run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No); let result = rx.recv().unwrap().result; <del> assert!(result == TrOk); </del> <ins> assert_eq!(result, TrOk); </ins> } // FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251)


panic!("an error message"); } let expected = "foobar"; <del> let failed_msg = "panic did not include expected string"; </del> <ins> let failed_msg = r#"panic did not contain expected string panic message: `"an error message"`, expected substring: `"foobar"`"#; </ins> let desc = TestDescAndFn { desc: TestDesc { name: StaticTestName("whatever"),


let (tx, rx) = channel(); run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No); let result = rx.recv().unwrap().result; <del> assert!(result == TrFailedMsg(format!("{} '{}'", failed_msg, expected))); </del> <ins> assert_eq!(result, TrFailedMsg(failed_msg.to_string())); } // FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251) #[test] #[cfg(not(target_os = "emscripten"))] fn test_should_panic_non_string_message_type() { use crate::tests::TrFailedMsg; fn f() { panic!(1i32); } let expected = "foobar"; let failed_msg = format!(r#"expected panic with string value, found non-string value: `{:?}` expected substring: `"foobar"`"#, TypeId::of::<i32>()); let desc = TestDescAndFn { desc: TestDesc { name: StaticTestName("whatever"), ignore: false, should_panic: ShouldPanic::YesWithMessage(expected), allow_fail: false, test_type: TestType::Unknown, }, testfn: DynTestFn(Box::new(f)), }; let (tx, rx) = channel(); run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No); let result = rx.recv().unwrap().result; assert_eq!(result, TrFailedMsg(failed_msg)); </ins> } // FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251)


let (tx, rx) = channel(); run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No); let result = rx.recv().unwrap().result; <del> assert!(result == TrFailedMsg("test did not panic as expected".to_string())); </del> <ins> assert_eq!(result, TrFailedMsg("test did not panic as expected".to_string())); </ins> } fn report_time_test_template(report_time: bool) -> Option<TestExecTime> {


]; for (a, b) in expected.iter().zip(filtered) { <del> assert!(*a == b.desc.name.to_string()); </del> <ins> assert_eq!(*a, b.desc.name.to_string()); </ins> } }


<ins> // edition:2018 trait Test<T> { fn is_some(self: T); //~ ERROR invalid `self` parameter type } async fn f() { let x = Some(2); if x.is_some() { println!("Some"); } } fn main() {} </ins>


<ins> error[E0307]: invalid `self` parameter type: T --> $DIR/issue-66312.rs:4:22 | LL |     fn is_some(self: T); |                      ^ | = note: type of `self` must be `Self` or a type that dereferences to it = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`) error: aborting due to previous error For more information about this error, try `rustc --explain E0307`. </ins>


"clippy_lints", "compiletest_rs", "derive-new", <ins> "git2", </ins> "lazy_static 1.3.0", "regex", "rustc-workspace-hack", "rustc_tools_util 0.2.0", "semver", "serde", <ins> "tempfile", </ins> "tester", ]


<del> Subproject commit 7b8e8293d08d298579470f9d6c74731043c6601a </del> <ins> Subproject commit 7a943a9dfcdca98e5988da6d0b7d2f83a364b5ba </ins>


impl<'tcx> MirPass<'tcx> for SimplifyArmIdentity { fn run_pass(&self, _: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut Body<'tcx>) { <del> for bb in body.basic_blocks_mut() { </del> <ins> let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut(); for bb in basic_blocks { </ins> // Need 3 statements: let (s0, s1, s2) = match &mut *bb.statements { [s0, s1, s2] => (s0, s1, s2),


Some(x) => x, }; if local_tmp_s0 != local_tmp_s1 <ins> // The field-and-variant information match up. </ins> || vf_s0 != vf_s1 <ins> // Source and target locals have the same type. // FIXME(Centril | oli-obk): possibly relax to same layout? || local_decls[local_0].ty != local_decls[local_1].ty // We're setting the discriminant of `local_0` to this variant. </ins> || Some((local_0, vf_s0.var_idx)) != match_set_discr(s2) { continue;


<ins> // Checks that `SimplifyArmIdentity` is not applied if enums have incompatible layouts. // Regression test for issue #66856. // // compile-flags: -Zmir-opt-level=2 enum Src { Foo(u8), Bar, } enum Dst { Foo(u8), } fn main() { let e: Src = Src::Foo(0); let _: Dst = match e { Src::Foo(x) => Dst::Foo(x), Src::Bar => Dst::Foo(0), }; } // END RUST SOURCE // START rustc.main.SimplifyArmIdentity.before.mir // fn main() -> () { //     ... //     bb0: { //         StorageLive(_1); //         ((_1 as Foo).0: u8) = const 0u8; //         discriminant(_1) = 0; //         StorageLive(_2); //         _3 = discriminant(_1); //         switchInt(move _3) -> [0isize: bb3, 1isize: bb1, otherwise: bb2]; //     } //     bb1: { //         ((_2 as Foo).0: u8) = const 0u8; //         discriminant(_2) = 0; //         goto -> bb4; //     } //     ... //     bb3: { //         _4 = ((_1 as Foo).0: u8); //         ((_2 as Foo).0: u8) = move _4; //         discriminant(_2) = 0; //         goto -> bb4; //     } //     ... // } // END rustc.main.SimplifyArmIdentity.before.mir // START rustc.main.SimplifyArmIdentity.after.mir // fn main() -> () { //     ... //     bb0: { //         StorageLive(_1); //         ((_1 as Foo).0: u8) = const 0u8; //         discriminant(_1) = 0; //         StorageLive(_2); //         _3 = discriminant(_1); //         switchInt(move _3) -> [0isize: bb3, 1isize: bb1, otherwise: bb2]; //     } //     bb1: { //         ((_2 as Foo).0: u8) = const 0u8; //         discriminant(_2) = 0; //         goto -> bb4; //     } //     ... //     bb3: { //         _4 = ((_1 as Foo).0: u8); //         ((_2 as Foo).0: u8) = move _4; //         discriminant(_2) = 0; //         goto -> bb4; //     } //     ... // } // END rustc.main.SimplifyArmIdentity.after.mir </ins>


<ins> // This used to mis-compile because the mir-opt `SimplifyArmIdentity` // did not check that the types matched up in the `Ok(r)` branch. // // run-pass // compile-flags: -Zmir-opt-level=2 #[derive(Debug, PartialEq, Eq)] enum SpecialsRes { Res(u64) } fn e103() -> SpecialsRes { if let Ok(r) = "1".parse() { SpecialsRes::Res(r) } else { SpecialsRes::Res(42) } } fn main() { assert_eq!(e103(), SpecialsRes::Res(1)); } </ins>


let tcx = self.infcx.tcx; let generics = tcx.generics_of(self.mir_def_id); let param = generics.type_param(&param_ty, tcx); <del> let generics = tcx.hir().get_generics(self.mir_def_id).unwrap(); suggest_constraining_type_param( generics, &mut err, &param.name.as_str(), "Copy", tcx.sess.source_map(), span, ); </del> <ins> if let Some(generics) = tcx.hir().get_generics(self.mir_def_id) { suggest_constraining_type_param( generics, &mut err, &param.name.as_str(), "Copy", tcx.sess.source_map(), span, ); } </ins> } let span = if let Some(local) = place.as_local() { let decl = &self.body.local_decls[local];


<ins> // edition:2018 struct Ia<S>(S); impl<S> Ia<S> { fn partial(_: S) {} fn full(self) {} async fn crash(self) { Self::partial(self.0); Self::full(self); //~ ERROR use of moved value: `self` } } fn main() {} </ins>


<ins> error[E0382]: use of moved value: `self` --> $DIR/issue-66958-non-copy-infered-type-arg.rs:11:20 | LL |         Self::partial(self.0); |                       ------ value moved here LL |         Self::full(self); |                    ^^^^ value used here after partial move | = note: move occurs because `self.0` has type `S`, which does not implement the `Copy` trait error: aborting due to previous error For more information about this error, try `rustc --explain E0382`. </ins>


# - thumbv7em-none-eabihf (Bare Cortex-M4F, M7F, FPU, hardfloat) # - thumbv7m-none-eabi (Bare Cortex-M3) <del> # only-thumbv6m-none-eabi # only-thumbv7em-none-eabi # only-thumbv7em-none-eabihf # only-thumbv7m-none-eabi </del> <ins> # only-thumb </ins> # For cargo setting RUSTC := $(RUSTC_ORIGINAL)


CRATE_URL := https://github.com/rust-embedded/cortex-m CRATE_SHA1 := a448e9156e2cb1e556e5441fd65426952ef4b927 # 0.5.0 <del> export RUSTFLAGS := --cap-lints=allow </del> <ins> # Don't make lints fatal, but they need to at least warn or they break Cargo's target info parsing. export RUSTFLAGS := --cap-lints=warn </ins> all: env


-include ../../run-make-fulldeps/tools.mk <del> # only-thumbv7m-none-eabi # only-thumbv6m-none-eabi </del> <ins> # only-thumb </ins> # How to run this # $ ./x.py clean


<del> [target.thumbv7m-none-eabi] # uncomment this to make `cargo run` execute programs on QEMU </del> <ins> [target.thumbv6m-none-eabi] # FIXME: Should be Cortex-M0, but Qemu used by CI is too old </ins> runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" <del> [target.thumbv6m-none-eabi] # uncomment this to make `cargo run` execute programs on QEMU # For now, we use cortex-m3 instead of cortex-m0 which are not supported by QEMU </del> <ins> [target.thumbv7m-none-eabi] </ins> runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" <ins> [target.thumbv7em-none-eabi] runner = "qemu-system-arm -cpu cortex-m4 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" [target.thumbv7em-none-eabihf] runner = "qemu-system-arm -cpu cortex-m4 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" [target.thumbv8m.base-none-eabi] # FIXME: Should be the Cortex-M23, bt Qemu does not currently support it runner = "qemu-system-arm -cpu cortex-m33 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" [target.thumbv8m.main-none-eabi] runner = "qemu-system-arm -cpu cortex-m33 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" [target.thumbv8m.main-none-eabihf] runner = "qemu-system-arm -cpu cortex-m33 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" </ins> [target.'cfg(all(target_arch = "arm", target_os = "none"))'] # uncomment ONE of these three option to make `cargo run` start a GDB session # which option to pick depends on your system


# "-C", "linker=arm-none-eabi-gcc", # "-C", "link-arg=-Wl,-Tlink.x", # "-C", "link-arg=-nostartfiles", <del> ] </del>  No newline at end of file <ins> ] </ins>


<ins> # This file is automatically @generated by Cargo. # It is not intended for manual editing. [[package]] name = "aligned" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "as-slice 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "as-slice" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", "generic-array 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "bare-metal" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cortex-m" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aligned 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "bare-metal 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cortex-m-rt" version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cortex-m-rt-macros 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cortex-m-rt-macros" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cortex-m-semihosting" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cortex-m 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "example" version = "0.1.0" dependencies = [ "cortex-m 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "cortex-m-rt 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", "cortex-m-semihosting 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "panic-halt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "generic-array" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "generic-array" version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "panic-halt" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "proc-macro2" version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "quote" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "r0" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustc_version" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "semver" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "semver-parser" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "stable_deref_trait" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "syn" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "typenum" version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "unicode-xid" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "vcell" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "volatile-register" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "vcell 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [metadata] "checksum aligned 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eb1ce8b3382016136ab1d31a1b5ce807144f8b7eb2d5f16b2108f0f07edceb94" "checksum as-slice 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "be6b7e95ac49d753f19cab5a825dea99a1149a04e4e3230b33ae16e120954c04" "checksum bare-metal 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" "checksum cortex-m 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2954942fbbdd49996704e6f048ce57567c3e1a4e2dc59b41ae9fde06a01fc763" "checksum cortex-m-rt 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "33a716cd7d8627fae3892c2eede9249e50d2d79aedfb43ca28dad9a2b23876d9" "checksum cortex-m-rt-macros 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "72b1073338d1e691b3b7aaf6bd61993e589ececce9242a02dfa5453e1b98918d" "checksum cortex-m-semihosting 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "113ef0ecffee2b62b58f9380f4469099b30e9f9cbee2804771b4203ba1762cfa" "checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" "checksum generic-array 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0ed1e761351b56f54eb9dcd0cfaca9fd0daecf93918e1cfc01c8a3d26ee7adcd" "checksum panic-halt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812" "checksum proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" "checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" "checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" "checksum vcell 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "876e32dcadfe563a4289e994f7cb391197f362b6315dc45e8ba4aa6f564a4b3c" "checksum volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286" </ins>


edition = "2018" [dependencies] <del> cortex-m = "0.5.4" cortex-m-rt = "=0.5.4" </del> <ins> cortex-m = "0.6.2" cortex-m-rt = "0.6.11" </ins> panic-halt = "0.2.0" cortex-m-semihosting = "0.3.1"


<del> // #![feature(stdsimd)] </del> #![no_main] #![no_std] use core::fmt::Write;


use cortex_m_rt::entry; use cortex_m_semihosting as semihosting; <del> //FIXME: This imports the provided #[panic_handler]. #[allow(rust_2018_idioms)] extern crate panic_halt; entry!(main); </del> <ins> use panic_halt as _; #[entry] </ins> fn main() -> ! { let x = 42;


// Check timestamps. let mut inputs = inputs.clone(); <del> inputs.add_path(&testpaths.file); </del> <ins> // Use `add_dir` to account for run-make tests, which use their individual directory inputs.add_dir(&testpaths.file); </ins> for aux in &props.aux { let path = testpaths.file.parent().unwrap().join("auxiliary").join(aux);


} // Error possibly reported in `check_assign` so avoid emitting error again. <del> err.emit_unless(expression.filter(|e| fcx.is_assign_to_bool(e, expected)) .is_some()); </del> <ins> let assign_to_bool = expression // #67273: Use initial expected type as opposed to `expected`. // Otherwise we end up using prior coercions in e.g. a `match` expression: // ``` // match i { //     0 => true, // Because of this... //     1 => i = 1, // ...`expected == bool` now, but not when checking `i = 1`. //     _ => (), // }; // ``` .filter(|e| fcx.is_assign_to_bool(e, self.expected_ty())) .is_some(); err.emit_unless(assign_to_bool); </ins> self.final_ty = Some(fcx.tcx.types.err); }


<ins> fn main() { let mut i: i64; // Expected type is an inference variable `?T` // because the `match` is used as a statement. // This is the "initial" type of the `coercion`. match i { // Add `bool` to the overall `coercion`. 0 => true, // Necessary to cause the ICE: 1 => true, // Suppose that we had `let _: bool = match i { ... }`. // In that case, as the expected type would be `bool`, // we would suggest `i == 1` as a fix. // // However, no type error happens when checking `i = 1` because `expected == ?T`, // which will unify with `typeof(i = 1) == ()`. // // However, in #67273, we would delay the unification of this arm with the above // because we used the hitherto accumulated coercion as opposed to the "initial" type. 2 => i = 1, //~^ ERROR match arms have incompatible types _ => (), } } </ins>


<ins> error[E0308]: match arms have incompatible types --> $DIR/issue-67273-assignment-match-prior-arm-bool-expected-unit.rs:22:14 | LL | /     match i { LL | |         // Add `bool` to the overall `coercion`. LL | |         0 => true, | |              ---- this is found to be of type `bool` LL | | LL | |         // Necessary to cause the ICE: LL | |         1 => true, | |              ---- this is found to be of type `bool` ...  | LL | |         2 => i = 1, | |              ^^^^^ expected `bool`, found `()` ...  | LL | |         _ => (), LL | |     } | |_____- `match` arms have incompatible types error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. </ins>


Ok(mplace) => { // Since evaluation had no errors, valiate the resulting constant: let validation = try { <del> // FIXME do not validate promoteds until a decision on // https://github.com/rust-lang/rust/issues/67465 and // https://github.com/rust-lang/rust/issues/67534 is made. // Promoteds can contain unexpected `UnsafeCell` and reference `static`s, but their // otherwise restricted form ensures that this is still sound. We just lose the // extra safety net of some of the dynamic checks. They can also contain invalid // values, but since we do not usually check intermediate results of a computation // for validity, it might be surprising to do that here. if cid.promoted.is_none() { let mut ref_tracking = RefTracking::new(mplace); let mut inner = false; while let Some((mplace, path)) = ref_tracking.todo.pop() { let mode = match tcx.static_mutability(cid.instance.def_id()) { Some(_) => CtfeValidationMode::Regular, // a `static` None => CtfeValidationMode::Const { inner }, }; ecx.const_validate_operand(mplace.into(), path, &mut ref_tracking, mode)?; inner = true; } </del> <ins> let mut ref_tracking = RefTracking::new(mplace); let mut inner = false; while let Some((mplace, path)) = ref_tracking.todo.pop() { let mode = match tcx.static_mutability(cid.instance.def_id()) { Some(_) if cid.promoted.is_some() => { // Promoteds in statics are allowed to point to statics. CtfeValidationMode::Const { inner, allow_static_ptrs: true } } Some(_) => CtfeValidationMode::Regular, // a `static` None => CtfeValidationMode::Const { inner, allow_static_ptrs: false }, }; ecx.const_validate_operand(mplace.into(), path, &mut ref_tracking, mode)?; inner = true; </ins> } }; if let Err(error) = validation {


pub enum CtfeValidationMode { /// Regular validation, nothing special happening. Regular, <del> /// Validation of a `const`. `inner` says if this is an inner, indirect allocation (as opposed /// to the top-level const allocation). /// Being an inner allocation makes a difference because the top-level allocation of a `const` /// is copied for each use, but the inner allocations are implicitly shared. Const { inner: bool }, </del> <ins> /// Validation of a `const`. /// `inner` says if this is an inner, indirect allocation (as opposed to the top-level const /// allocation). Being an inner allocation makes a difference because the top-level allocation /// of a `const` is copied for each use, but the inner allocations are implicitly shared. /// `allow_static_ptrs` says if pointers to statics are permitted (which is the case for promoteds in statics). Const { inner: bool, allow_static_ptrs: bool }, </ins> } /// State for tracking recursive validation of references


if let Some(GlobalAlloc::Static(did)) = alloc_kind { assert!(!self.ecx.tcx.is_thread_local_static(did)); assert!(self.ecx.tcx.is_static(did)); <del> if matches!(self.ctfe_mode, Some(CtfeValidationMode::Const { .. })) { </del> <ins> if matches!( self.ctfe_mode, Some(CtfeValidationMode::Const { allow_static_ptrs: false, .. }) ) { </ins> // See const_eval::machine::MemoryExtra::can_access_statics for why // this check is so important. // This check is reachable when the const just referenced the static,


// Sanity check: `builtin_deref` does not know any pointers that are not primitive. assert!(op.layout.ty.builtin_deref(true).is_none()); <del> // Special check preventing `UnsafeCell` in constants </del> <ins> // Special check preventing `UnsafeCell` in the inner part of constants </ins> if let Some(def) = op.layout.ty.ty_adt_def() { <del> if matches!(self.ctfe_mode, Some(CtfeValidationMode::Const { inner: true })) </del> <ins> if matches!(self.ctfe_mode, Some(CtfeValidationMode::Const { inner: true, .. })) </ins> && Some(def.did) == self.ecx.tcx.lang_items().unsafe_cell_type() { throw_validation_failure!(self.path, { "`UnsafeCell` in a `const`" });


if let (local, []) = (&place.local, proj_base) { let decl = &self.body.local_decls[*local]; if decl.internal { <del> // Internal locals are used in the `move_val_init` desugaring. // We want to check unsafety against the source info of the // desugaring, rather than the source info of the RHS. self.source_info = self.body.local_decls[*local].source_info; } else if let LocalInfo::StaticRef { def_id, .. } = decl.local_info { if self.tcx.is_mutable_static(def_id) { self.require_unsafe( "use of mutable static", "mutable statics can be mutated by multiple threads: aliasing  violations or data races will cause undefined behavior", UnsafetyViolationKind::General, ); return; } else if self.tcx.is_foreign_item(def_id) { self.require_unsafe( "use of extern static", "extern statics are not controlled by the Rust type system:  invalid data, aliasing violations or data races will cause  undefined behavior", UnsafetyViolationKind::General, ); return; </del> <ins> if let LocalInfo::StaticRef { def_id, .. } = decl.local_info { if self.tcx.is_mutable_static(def_id) { self.require_unsafe( "use of mutable static", "mutable statics can be mutated by multiple threads: aliasing  violations or data races will cause undefined behavior", UnsafetyViolationKind::General, ); return; } else if self.tcx.is_foreign_item(def_id) { self.require_unsafe( "use of extern static", "extern statics are not controlled by the Rust type system:  invalid data, aliasing violations or data races will cause  undefined behavior", UnsafetyViolationKind::General, ); return; } } else { // Internal locals are used in the `move_val_init` desugaring. // We want to check unsafety against the source info of the // desugaring, rather than the source info of the RHS. self.source_info = self.body.local_decls[*local].source_info; </ins> } } }


} if let ExprKind::StaticRef { def_id, .. } = expr.kind { let is_thread_local = this.hir.tcx().has_attr(def_id, sym::thread_local); <ins> local_decl.internal = true; </ins> local_decl.local_info = LocalInfo::StaticRef { def_id, is_thread_local }; } this.local_decls.push(local_decl)


} fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { <del> let scope = self.region_scope_tree.temporary_scope(expr.hir_id.local_id); </del> match &expr.kind { ExprKind::Call(callee, args) => match &callee.kind { ExprKind::Path(qpath) => {


} _ => intravisit::walk_expr(self, expr), }, <del> ExprKind::Path(qpath) => { let res = self.fcx.tables.borrow().qpath_res(qpath, expr.hir_id); if let Res::Def(DefKind::Static, def_id) = res { // Statics are lowered to temporary references or // pointers in MIR, so record that type. let ptr_ty = self.fcx.tcx.static_ptr_ty(def_id); self.record(ptr_ty, scope, Some(expr), expr.span); } } </del> _ => intravisit::walk_expr(self, expr), } self.expr_count += 1; <ins> let scope = self.region_scope_tree.temporary_scope(expr.hir_id.local_id); </ins> // If there are adjustments, then record the final type -- // this is the actual value that is being produced. if let Some(adjusted_ty) = self.fcx.tables.borrow().expr_ty_adjusted_opt(expr) {


<ins> // build-pass // edition:2018 static mut A: [i32; 5] = [1, 2, 3, 4, 5]; fn is_send_sync<T: Send + Sync>(_: T) {} async fn fun() { let u = unsafe { A[async { 1 }.await] }; unsafe { match A { i if async { true }.await => (), _ => (), } } } fn main() { let index_block = async { let u = unsafe { A[async { 1 }.await] }; }; let match_block = async { unsafe { match A { i if async { true }.await => (), _ => (), } } }; is_send_sync(index_block); is_send_sync(match_block); is_send_sync(fun()); } </ins>


<ins> // build-pass #![feature(generators)] static mut A: [i32; 5] = [1, 2, 3, 4, 5]; fn is_send_sync<T: Send + Sync>(_: T) {} fn main() { unsafe { let gen_index = static || { let u = A[{ yield; 1 }]; }; let gen_match = static || match A { i if { yield; true } => { () } _ => (), }; is_send_sync(gen_index); is_send_sync(gen_match); } } </ins>


<del> Subproject commit c807fbc8ba41432388b6f590668ba81314c07c32 </del> <ins> Subproject commit d9e38f57c125c5ac50397ec8a006fe49f17cd96c </ins>


<del> Subproject commit 4da2b2149ca1c6a3331260dfcbb2175c51f2842d </del> <ins> Subproject commit 4e44aa010c4c7d616182a3078cafb39da6f6c0a2 </ins>


<del> Subproject commit 732825dcff6d1f115225305ce5e0c9c9d876a0ff </del> <ins> Subproject commit e8642c7a2900bed28003a98d4db8b62290ac802f </ins>


// listing. let main_ret_ty = cx.tcx().erase_regions(&main_ret_ty.no_bound_vars().unwrap()); <del> if cx.get_defined_value("main").is_some() { </del> <ins> if cx.get_declared_value("main").is_some() { </ins> // FIXME: We should be smart and show a better diagnostic here. cx.sess() <del> .struct_span_err(sp, "entry symbol `main` defined multiple times") </del> <ins> .struct_span_err(sp, "entry symbol `main` declared multiple times") </ins> .help("did you use `#[no_mangle]` on `fn main`? Use `#[start]` instead") .emit(); cx.sess().abort_if_errors();


// build-fail // <del> // error-pattern: entry symbol `main` defined multiple times </del> <ins> // error-pattern: entry symbol `main` declared multiple times </ins> // FIXME https://github.com/rust-lang/rust/issues/59774 // normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*n" -> ""


<del> error: entry symbol `main` defined multiple times </del> <ins> error: entry symbol `main` declared multiple times </ins> --> $DIR/dupe-symbols-7.rs:12:1 | LL | fn main(){}


<ins> // build-fail // error-pattern: entry symbol `main` declared multiple times // // See #67946. #![allow(warnings)] fn main() { extern "Rust" { fn main(); } unsafe { main(); } } </ins>


<ins> error: entry symbol `main` declared multiple times --> $DIR/dupe-symbols-8.rs:7:1 | LL | / fn main() { LL | |     extern "Rust" { LL | |      fn main(); LL | |     } LL | |     unsafe { main(); } LL | | } | |_^ | = help: did you use `#[no_mangle]` on `fn main`? Use `#[start]` instead error: aborting due to previous error </ins>


Some("std::ops::Add"), ), hir::BinOpKind::Sub => ( <del> format!("cannot substract `{}` from `{}`", rhs_ty, lhs_ty), </del> <ins> format!("cannot subtract `{}` from `{}`", rhs_ty, lhs_ty), </ins> Some("std::ops::Sub"), ), hir::BinOpKind::Mul => (


a + a; //~ ERROR cannot add `A` to `A` <del> a - a; //~ ERROR cannot substract `A` from `A` </del> <ins> a - a; //~ ERROR cannot subtract `A` from `A` </ins> a * a; //~ ERROR cannot multiply `A` to `A`


| = note: an implementation of `std::ops::Add` might be missing for `A` <del> error[E0369]: cannot substract `A` from `A` </del> <ins> error[E0369]: cannot subtract `A` from `A` </ins> --> $DIR/issue-28837.rs:8:7 | LL |     a - a;


if let Some(item) = module .res .and_then(|res| res.mod_def_id()) <ins> // If the module is `self`, i.e. the current crate, // there will be no corresponding item. .filter(|def_id| def_id.index != CRATE_DEF_INDEX || def_id.krate != LOCAL_CRATE) </ins> .and_then(|def_id| self.tcx.hir().as_local_hir_id(def_id)) .map(|module_hir_id| self.tcx.hir().expect_item(module_hir_id)) {


<ins> // check-pass pub extern crate self as name; pub use name::name as bug; fn main() {} </ins>


dylibs: FxHashMap<PathBuf, PathKind>, ) -> Option<(Svh, Library)> { let mut slot = None; <ins> // Order here matters, rmeta should come first. See comment in // `extract_one` below. </ins> let source = CrateSource { <del> rlib: self.extract_one(rlibs, CrateFlavor::Rlib, &mut slot), </del> rmeta: self.extract_one(rmetas, CrateFlavor::Rmeta, &mut slot), <ins> rlib: self.extract_one(rlibs, CrateFlavor::Rlib, &mut slot), </ins> dylib: self.extract_one(dylibs, CrateFlavor::Dylib, &mut slot), }; slot.map(|(svh, metadata)| (svh, Library { source, metadata })) } <ins> fn needs_crate_flavor(&self, flavor: CrateFlavor) -> bool { if flavor == CrateFlavor::Dylib && self.is_proc_macro == Some(true) { return true; } // The all loop is because `--crate-type=rlib --crate-type=rlib` is // legal and produces both inside this type. let is_rlib = self.sess.crate_types.borrow().iter().all(|c| *c == config::CrateType::Rlib); let needs_object_code = self.sess.opts.output_types.should_codegen(); // If we're producing an rlib, then we don't need object code. // Or, if we're not producing object code, then we don't need it either // (e.g., if we're a cdylib but emitting just metadata). if is_rlib || !needs_object_code { flavor == CrateFlavor::Rmeta } else { // we need all flavors (perhaps not true, but what we do for now) true } } </ins> // Attempts to extract *one* library from the set `m`. If the set has no // elements, `None` is returned. If the set has more than one element, then // the errors and notes are emitted about the set of libraries.


let mut ret: Option<(PathBuf, PathKind)> = None; let mut error = 0; <ins> // If we are producing an rlib, and we've already loaded metadata, then // we should not attempt to discover further crate sources (unless we're // locating a proc macro; exact logic is in needs_crate_flavor). This means // that under -Zbinary-dep-depinfo we will not emit a dependency edge on // the *unused* rlib, and by returning `None` here immediately we // guarantee that we do indeed not use it. // // See also #68149 which provides more detail on why emitting the // dependency on the rlib is a bad thing. // // We currenty do not verify that these other sources are even in sync, // and this is arguably a bug (see #10786), but because reading metadata // is quite slow (especially from dylibs) we currently do not read it // from the other crate sources. </ins> if slot.is_some() { <del> // FIXME(#10786): for an optimization, we only read one of the //                libraries' metadata sections. In theory we should //                read both, but reading dylib metadata is quite //                slow. if m.is_empty() { </del> <ins> if m.is_empty() || !self.needs_crate_flavor(flavor) { </ins> return None; } else if m.len() == 1 { return Some(m.into_iter().next().unwrap());


// run-pass // Test that using rlibs and rmeta dep crates work together. Specifically, that <del> // there can be both an rmeta and an rlib file and rustc will prefer the rlib. </del> <ins> // there can be both an rmeta and an rlib file and rustc will prefer the rmeta // file. // // This behavior is simply making sure this doesn't accidentally change; in this // case we want to make sure that the rlib isn't being used as that would cause // bugs in -Zbinary-dep-depinfo (see #68298). </ins> // aux-build:rmeta-rmeta.rs // aux-build:rmeta-rlib-rpass.rs


use rmeta_aux::Foo; pub fn main() { <del> let _ = Foo { field: 42 }; </del> <ins> let _ = Foo { field2: 42 }; </ins> }


<del> Subproject commit fd0428f622feee209e6014b802f5717d48d9e978 </del> <ins> Subproject commit 3e74853d1f9893cf2a47f28b658711d8f9f97b6b </ins>


/// `failure` describes the required ordering for the load operation that takes place when /// the comparison fails. Using [`Acquire`] as success ordering makes the store part /// of this operation [`Relaxed`], and using [`Release`] makes the successful load <del> /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`] /// and must be equivalent to or weaker than the success ordering. </del> <ins> /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]. </ins> /// /// **Note:** This method is only available on platforms that support atomic /// operations on `u8`.


/// Using [`Acquire`] as success ordering makes the store part of this /// operation [`Relaxed`], and using [`Release`] makes the final successful /// load [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], <del> /// [`Acquire`] or [`Relaxed`] and must be equivalent to or weaker than the /// success ordering. </del> <ins> /// [`Acquire`] or [`Relaxed`]. </ins> /// /// **Note:** This method is only available on platforms that support atomic /// operations on `u8`.


/// `failure` describes the required ordering for the load operation that takes place when /// the comparison fails. Using [`Acquire`] as success ordering makes the store part /// of this operation [`Relaxed`], and using [`Release`] makes the successful load <del> /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`] /// and must be equivalent to or weaker than the success ordering. </del> <ins> /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]. </ins> /// /// **Note:** This method is only available on platforms that support atomic /// operations on pointers.


/// Using [`Acquire`] as success ordering makes the store part of this /// operation [`Relaxed`], and using [`Release`] makes the final successful /// load [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], <del> /// [`Acquire`] or [`Relaxed`] and must be equivalent to or weaker than the /// success ordering. </del> <ins> /// [`Acquire`] or [`Relaxed`]. </ins> /// /// **Note:** This method is only available on platforms that support atomic /// operations on pointers.


/// `failure` describes the required ordering for the load operation that takes place when /// the comparison fails. Using [`Acquire`] as success ordering makes the store part /// of this operation [`Relaxed`], and using [`Release`] makes the successful load <del> /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`] /// and must be equivalent to or weaker than the success ordering. </del> <ins> /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]. </ins> /// /// **Note**: This method is only available on platforms that support atomic operations on #[doc = concat!("[`", $s_int_type, "`].")]


/// /// Using [`Acquire`] as success ordering makes the store part /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load <del> /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`] /// and must be equivalent to or weaker than the success ordering. </del> <ins> /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]. </ins> /// /// **Note**: This method is only available on platforms that support atomic operations on #[doc = concat!("[`", $s_int_type, "`].")]


let (val, ok) = unsafe { match (success, failure) { (Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed_relaxed(dst, old, new), <del> //(Relaxed, Acquire) => intrinsics::atomic_cxchg_relaxed_acquire(dst, old, new), //(Relaxed, SeqCst) => intrinsics::atomic_cxchg_relaxed_seqcst(dst, old, new), </del> <ins> #[cfg(not(bootstrap))] (Relaxed, Acquire) => intrinsics::atomic_cxchg_relaxed_acquire(dst, old, new), #[cfg(not(bootstrap))] (Relaxed, SeqCst) => intrinsics::atomic_cxchg_relaxed_seqcst(dst, old, new), </ins> (Acquire, Relaxed) => intrinsics::atomic_cxchg_acquire_relaxed(dst, old, new), (Acquire, Acquire) => intrinsics::atomic_cxchg_acquire_acquire(dst, old, new), <del> //(Acquire, SeqCst) => intrinsics::atomic_cxchg_acquire_seqcst(dst, old, new), </del> <ins> #[cfg(not(bootstrap))] (Acquire, SeqCst) => intrinsics::atomic_cxchg_acquire_seqcst(dst, old, new), </ins> (Release, Relaxed) => intrinsics::atomic_cxchg_release_relaxed(dst, old, new), <del> //(Release, Acquire) => intrinsics::atomic_cxchg_release_acquire(dst, old, new), //(Release, SeqCst) => intrinsics::atomic_cxchg_release_seqcst(dst, old, new), </del> <ins> #[cfg(not(bootstrap))] (Release, Acquire) => intrinsics::atomic_cxchg_release_acquire(dst, old, new), #[cfg(not(bootstrap))] (Release, SeqCst) => intrinsics::atomic_cxchg_release_seqcst(dst, old, new), </ins> (AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_relaxed(dst, old, new), (AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel_acquire(dst, old, new), <del> //(AcqRel, SeqCst) => intrinsics::atomic_cxchg_acqrel_seqcst(dst, old, new), </del> <ins> #[cfg(not(bootstrap))] (AcqRel, SeqCst) => intrinsics::atomic_cxchg_acqrel_seqcst(dst, old, new), </ins> (SeqCst, Relaxed) => intrinsics::atomic_cxchg_seqcst_relaxed(dst, old, new), (SeqCst, Acquire) => intrinsics::atomic_cxchg_seqcst_acquire(dst, old, new), (SeqCst, SeqCst) => intrinsics::atomic_cxchg_seqcst_seqcst(dst, old, new), (_, AcqRel) => panic!("there is no such thing as an acquire-release failure ordering"), (_, Release) => panic!("there is no such thing as a release failure ordering"), <ins> #[cfg(bootstrap)] </ins> _ => panic!("a failure ordering can't be stronger than a success ordering"), } };


let (val, ok) = unsafe { match (success, failure) { (Relaxed, Relaxed) => intrinsics::atomic_cxchgweak_relaxed_relaxed(dst, old, new), <del> //(Relaxed, Acquire) => intrinsics::atomic_cxchgweak_relaxed_acquire(dst, old, new), //(Relaxed, SeqCst) => intrinsics::atomic_cxchgweak_relaxed_seqcst(dst, old, new), </del> <ins> #[cfg(not(bootstrap))] (Relaxed, Acquire) => intrinsics::atomic_cxchgweak_relaxed_acquire(dst, old, new), #[cfg(not(bootstrap))] (Relaxed, SeqCst) => intrinsics::atomic_cxchgweak_relaxed_seqcst(dst, old, new), </ins> (Acquire, Relaxed) => intrinsics::atomic_cxchgweak_acquire_relaxed(dst, old, new), (Acquire, Acquire) => intrinsics::atomic_cxchgweak_acquire_acquire(dst, old, new), <del> //(Acquire, SeqCst) => intrinsics::atomic_cxchgweak_acquire_seqcst(dst, old, new), </del> <ins> #[cfg(not(bootstrap))] (Acquire, SeqCst) => intrinsics::atomic_cxchgweak_acquire_seqcst(dst, old, new), </ins> (Release, Relaxed) => intrinsics::atomic_cxchgweak_release_relaxed(dst, old, new), <del> //(Release, Acquire) => intrinsics::atomic_cxchgweak_release_acquire(dst, old, new), //(Release, SeqCst) => intrinsics::atomic_cxchgweak_release_seqcst(dst, old, new), </del> <ins> #[cfg(not(bootstrap))] (Release, Acquire) => intrinsics::atomic_cxchgweak_release_acquire(dst, old, new), #[cfg(not(bootstrap))] (Release, SeqCst) => intrinsics::atomic_cxchgweak_release_seqcst(dst, old, new), </ins> (AcqRel, Relaxed) => intrinsics::atomic_cxchgweak_acqrel_relaxed(dst, old, new), (AcqRel, Acquire) => intrinsics::atomic_cxchgweak_acqrel_acquire(dst, old, new), <del> //(AcqRel, SeqCst) => intrinsics::atomic_cxchgweak_acqrel_seqcst(dst, old, new), </del> <ins> #[cfg(not(bootstrap))] (AcqRel, SeqCst) => intrinsics::atomic_cxchgweak_acqrel_seqcst(dst, old, new), </ins> (SeqCst, Relaxed) => intrinsics::atomic_cxchgweak_seqcst_relaxed(dst, old, new), (SeqCst, Acquire) => intrinsics::atomic_cxchgweak_seqcst_acquire(dst, old, new), (SeqCst, SeqCst) => intrinsics::atomic_cxchgweak_seqcst_seqcst(dst, old, new), (_, AcqRel) => panic!("there is no such thing as an acquire-release failure ordering"), (_, Release) => panic!("there is no such thing as a release failure ordering"), <ins> #[cfg(bootstrap)] </ins> _ => panic!("a failure ordering can't be stronger than a success ordering"), } };


<ins> // build-pass // Verify that the compiler doesn't ICE during const prop while evaluating the index operation. #![allow(unconditional_panic)] fn main() { let cols = [0u32; 0]; cols[0]; } </ins>


ty_span: Span, ) { if variant.recovered { <ins> self.set_tainted_by_errors(); </ins> return; } let mut err = self.type_error_struct_with_diag(


<ins> // Regression test for #69378: no type for node after struct parse recovery struct Foo { 0: u8 } //~ ERROR expected identifier fn test(f: Foo) { Foo{foo: 4, ..f}; } fn main() {} </ins>


<ins> error: expected identifier, found `0` --> $DIR/issue-69378-ice-on-invalid-type-node-after-recovery.rs:3:14 | LL | struct Foo { 0: u8 } |              ^ expected identifier error: aborting due to previous error </ins>


[[package]] name = "git2" <del> version = "0.11.0" </del> <ins> version = "0.12.0" </ins> source = "registry+https://github.com/rust-lang/crates.io-index" <del> checksum = "77519ef7c5beee314d0804d4534f01e0f9e8d9acdee2b7a48627e590b27e0ec4" </del> <ins> checksum = "26e07ef27260a78f7e8d218ebac2c72f2c4db50493741b190b6e8eade1da7c68" </ins> dependencies = [ "bitflags", "libc",


[[package]] name = "git2-curl" <del> version = "0.12.0" </del> <ins> version = "0.13.0" </ins> source = "registry+https://github.com/rust-lang/crates.io-index" <del> checksum = "d2559abb1d87d27668d31bd868a000f0e2e0065d10e78961b62da95d7a7f1cc7" </del> <ins> checksum = "af1754ec4170e7dcaf9bb43743bb16eddb8d827b2e0291deb6f220a6e16fe46a" </ins> dependencies = [ "curl", "git2",


[[package]] name = "libgit2-sys" <del> version = "0.10.0" </del> <ins> version = "0.11.0+0.99.0" </ins> source = "registry+https://github.com/rust-lang/crates.io-index" <del> checksum = "d9ec6bca50549d34a392611dde775123086acbd994e3fff64954777ce2dc2e51" </del> <ins> checksum = "4d5d1459353d397a029fb18862166338de938e6be976606bd056cf8f1a912ecf" </ins> dependencies = [ "cc", "libc",


<del> Subproject commit e57bd02999c9f40d52116e0beca7d1dccb0643de </del> <ins> Subproject commit bda50510d1daf6e9c53ad6ccf603da6e0fa8103f </ins>


<del> Subproject commit fc5d0cc583cb1cd35d58fdb7f3e0cfa12dccd6c0 </del> <ins> Subproject commit 8b7f7e667268921c278af94ae30a61e87a22b22b </ins>


source_file: Lrc<rustc_span::SourceFile>, override_span: Option<Span>, ) -> Self { <del> if source_file.src.is_none() { </del> <ins> // Make sure external source is loaded first, before accessing it. // While this can't show up during normal parsing, `retokenize` may // be called with a source file from an external crate. sess.source_map().ensure_source_file_source_present(source_file.clone()); // FIXME(eddyb) use `Lrc<str>` or similar to avoid cloning the `String`. let src = if let Some(src) = &source_file.src { src.clone() } else if let Some(src) = source_file.external_src.borrow().get_source() { src.clone() } else { </ins> sess.span_diagnostic .bug(&format!("cannot lex `source_file` without source: {}", source_file.name)); <del> } let src = (*source_file.src.as_ref().unwrap()).clone(); </del> <ins> }; </ins> StringReader { sess,


#[derive(PartialEq, Eq, Clone, Debug)] pub enum ExternalSourceKind { /// The external source has been loaded already. <del> Present(String), </del> <ins> Present(Lrc<String>), </ins> /// No attempt has been made to load the external source. AbsentOk, /// A failed attempt has been made to load the external source.


} } <del> pub fn get_source(&self) -> Option<&str> { </del> <ins> pub fn get_source(&self) -> Option<&Lrc<String>> { </ins> match self { ExternalSource::Foreign { kind: ExternalSourceKind::Present(ref src), .. } => Some(src), _ => None,


hasher.write(src.as_bytes()); if hasher.finish::<u128>() == self.src_hash { <del> *src_kind = ExternalSourceKind::Present(src); </del> <ins> *src_kind = ExternalSourceKind::Present(Lrc::new(src)); </ins> return true; } } else {


} } <ins> /// Checks that generic parameters are in the correct order, /// which is lifetimes, then types and then consts. (`<'a, T, const N: usize>`) </ins> fn validate_generic_param_order<'a>( sess: &Session, handler: &rustc_errors::Handler,


// Now create the real type and const parameters. let type_start = own_start - has_self as u32 + params.len() as u32; let mut i = 0; <del> params.extend(ast_generics.params.iter().filter_map(|param| { let kind = match param.kind { GenericParamKind::Type { ref default, synthetic, .. } => { if !allow_defaults && default.is_some() { if !tcx.features().default_type_parameter_fallback { tcx.struct_span_lint_hir( lint::builtin::INVALID_TYPE_PARAM_DEFAULT, param.hir_id, param.span, |lint| { lint.build( "defaults for type parameters are only allowed in  `struct`, `enum`, `type`, or `trait` definitions.", ) .emit(); }, ); } } ty::GenericParamDefKind::Type { has_default: default.is_some(), object_lifetime_default: object_lifetime_defaults .as_ref() .map_or(rl::Set1::Empty, |o| o[i]), synthetic, </del> <ins> // FIXME(const_generics): a few places in the compiler expect generic params // to be in the order lifetimes, then type params, then const params. // // To prevent internal errors in case const parameters are supplied before // type parameters we first add all type params, then all const params. params.extend(ast_generics.params.iter().filter_map(|param| { if let GenericParamKind::Type { ref default, synthetic, .. } = param.kind { if !allow_defaults && default.is_some() { if !tcx.features().default_type_parameter_fallback { tcx.struct_span_lint_hir( lint::builtin::INVALID_TYPE_PARAM_DEFAULT, param.hir_id, param.span, |lint| { lint.build( "defaults for type parameters are only allowed in  `struct`, `enum`, `type`, or `trait` definitions.", ) .emit(); }, ); </ins> } } <del> GenericParamKind::Const { .. } => ty::GenericParamDefKind::Const, _ => return None, }; let param_def = ty::GenericParamDef { index: type_start + i as u32, name: param.name.ident().name, def_id: tcx.hir().local_def_id(param.hir_id), pure_wrt_drop: param.pure_wrt_drop, kind, }; i += 1; Some(param_def) </del> <ins> let kind = ty::GenericParamDefKind::Type { has_default: default.is_some(), object_lifetime_default: object_lifetime_defaults .as_ref() .map_or(rl::Set1::Empty, |o| o[i]), synthetic, }; let param_def = ty::GenericParamDef { index: type_start + i as u32, name: param.name.ident().name, def_id: tcx.hir().local_def_id(param.hir_id), pure_wrt_drop: param.pure_wrt_drop, kind, }; i += 1; Some(param_def) } else { None } })); params.extend(ast_generics.params.iter().filter_map(|param| { if let GenericParamKind::Const { .. } = param.kind { let param_def = ty::GenericParamDef { index: type_start + i as u32, name: param.name.ident().name, def_id: tcx.hir().local_def_id(param.hir_id), pure_wrt_drop: param.pure_wrt_drop, kind: ty::GenericParamDefKind::Const, }; i += 1; Some(param_def) } else { None } </ins> })); // provide junk type parameter defs - the only place that


<ins> #![feature(const_generics)] //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash struct Bad<const N: usize, T> { //~ ERROR type parameters must be declared prior arr: [u8; { N }], another: T, } fn main() { } </ins>


<ins> error: type parameters must be declared prior to const parameters --> $DIR/argument_order.rs:4:28 | LL | struct Bad<const N: usize, T> { |           -----------------^- help: reorder the parameters: lifetimes, then types, then consts: `<T, const N: usize>` warning: the feature `const_generics` is incomplete and may cause the compiler to crash --> $DIR/argument_order.rs:1:12 | LL | #![feature(const_generics)] |            ^^^^^^^^^^^^^^ | = note: `#[warn(incomplete_features)]` on by default error: aborting due to previous error </ins>


// The collapse-docs pass won't combine sugared/raw doc attributes, or included files with // anything else, this will combine them for us. if let Some(doc) = attrs.collapsed_doc_value() { <del> self.collector.set_position(attrs.span.unwrap_or(DUMMY_SP)); </del> <ins> // Use the outermost invocation, so that doctest names come from where the docs were written. let span = attrs .span .map(|span| span.ctxt().outer_expn().expansion_cause().unwrap_or(span)) .unwrap_or(DUMMY_SP); self.collector.set_position(span); </ins> markdown::find_testable_code( &doc, self.collector,


<ins> #[macro_export] macro_rules! attrs_on_struct { ( $( #[$attr:meta] )* ) => { $( #[$attr] )* pub struct ExpandedStruct; } } </ins>


<ins> // edition:2018 // aux-build:extern_macros.rs </ins> // compile-flags:--test --test-args=--test-threads=1 // normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" // check-pass


//! assert_eq!(1 + 1, 2); //! ``` <ins> extern crate extern_macros as macros; use macros::attrs_on_struct; </ins> pub mod foo { /// ```


/// ``` pub fn bar() {} } <ins> attrs_on_struct! { /// ``` /// assert!(true); /// ``` } </ins>


<del> running 2 tests test $DIR/doctest-output.rs - (line 5) ... ok test $DIR/doctest-output.rs - foo::bar (line 11) ... ok </del> <ins> running 3 tests test $DIR/doctest-output.rs - (line 7) ... ok test $DIR/doctest-output.rs - ExpandedStruct (line 23) ... ok test $DIR/doctest-output.rs - foo::bar (line 17) ... ok </ins> <del> test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out </del> <ins> test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out </ins>


} /// Configuration for compiletest <del> #[derive(Clone)] </del> <ins> #[derive(Debug, Clone)] </ins> pub struct Config { /// `true` to to overwrite stderr/stdout files instead of complaining about changes in output. pub bless: bool,


emit_metadata: EmitMetadata, allow_unused: AllowUnused, ) -> Command { <del> let is_rustdoc = self.is_rustdoc(); </del> <ins> let is_aux = input_file.components().map(|c| c.as_os_str()).any(|c| c == "auxiliary"); let is_rustdoc = self.is_rustdoc() && !is_aux; </ins> let mut rustc = if !is_rustdoc { Command::new(&self.config.rustc_path) } else {


} } <ins> #[derive(Debug)] </ins> enum TargetLocation { ThisFile(PathBuf), ThisDirectory(PathBuf),


<ins> // Regression test for https://github.com/rust-lang/rust/issues/56445#issuecomment-629426939 // check-pass #![crate_type = "lib"] use std::marker::PhantomData; pub struct S<'a> { pub m1: PhantomData<&'a u8>, pub m2: [u8; S::size()], } impl<'a> S<'a> { pub const fn size() -> usize { 1 } pub fn new() -> Self { Self { m1: PhantomData, m2: [0; Self::size()], } } } </ins>


<ins> // check-pass pub struct A<'a>(&'a ()); impl<'a> A<'a> { const N: usize = 68; pub fn foo(&self) { let _b = [0; Self::N]; } } fn main() {} </ins>


<ins> #![feature(impl_trait_in_bindings)] #![allow(incomplete_features)] fn main() { const C: impl Copy = 0; match C { C | _ => {} //~ ERROR: opaque types cannot be used in patterns } } </ins>


<ins> error: opaque types cannot be used in patterns --> $DIR/issue-71042-opaquely-typed-constant-used-in-pattern.rs:7:9 | LL |         C | _ => {} |         ^ error: aborting due to previous error </ins>


<ins> // check-pass #![feature(type_alias_impl_trait)] pub type Successors<'a> = impl Iterator<Item = &'a ()>; pub fn f<'a>() -> Successors<'a> { None.into_iter() } pub trait Tr { type Item; } impl<'a> Tr for &'a () { type Item = Successors<'a>; } pub fn kazusa<'a>() -> <&'a () as Tr>::Item { None.into_iter() } fn main() {} </ins>


// figure out which generic parameter it corresponds to and return // the relevant type. let generics = match path.res { <del> Res::Def(DefKind::Ctor(..), def_id) => { </del> <ins> Res::Def(DefKind::Ctor(..), def_id) | Res::Def(DefKind::AssocTy, def_id) => { </ins> tcx.generics_of(tcx.parent(def_id).unwrap()) } Res::Def(_, def_id) => tcx.generics_of(def_id), <del> Res::Err => return tcx.types.err, </del> res => { tcx.sess.delay_span_bug( DUMMY_SP, <del> &format!("unexpected const parent path def {:?}", res,), </del> <ins> &format!( "unexpected const parent path def, parent: {:?}, def: {:?}", parent_node, res ), </ins> ); return tcx.types.err; }


.map(|param| tcx.type_of(param.def_id)) // This is no generic parameter associated with the arg. This is // probably from an extra arg where one is not needed. <del> .unwrap_or(tcx.types.err) </del> <ins> .unwrap_or_else(|| { tcx.sess.delay_span_bug( DUMMY_SP, &format!( "missing generic parameter for `AnonConst`, parent {:?}", parent_node ), ); tcx.types.err }) </ins> } else { tcx.sess.delay_span_bug( DUMMY_SP,


<ins> // check-pass #![feature(const_generics)] //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash pub struct Tuple; pub trait Trait<const I: usize> { type Input: From<<Self as Trait<I>>::Input>; } fn main() {} </ins>


<ins> warning: the feature `const_generics` is incomplete and may cause the compiler to crash --> $DIR/issue-66906.rs:3:12 | LL | #![feature(const_generics)] |            ^^^^^^^^^^^^^^ | = note: `#[warn(incomplete_features)]` on by default </ins>


<ins> // check-pass #![feature(const_generics)] //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash pub trait Trait<const N: usize>: From<<Self as Trait<N>>::Item> { type Item; } fn main() {} </ins>


<ins> warning: the feature `const_generics` is incomplete and may cause the compiler to crash --> $DIR/issue-70167.rs:3:12 | LL | #![feature(const_generics)] |            ^^^^^^^^^^^^^^ | = note: `#[warn(incomplete_features)]` on by default </ins>


span: Span,            // span of the field pattern, e.g., `x: 0` def: &'tcx ty::AdtDef, // definition of the struct or enum field: &'tcx ty::FieldDef, <ins> in_update_syntax: bool, </ins> ) { // definition of the field let ident = Ident::new(kw::Invalid, use_ctxt); let current_hir = self.current_item; let def_id = self.tcx.adjust_ident_and_get_scope(ident, def.did, current_hir).1; if !def.is_enum() && !field.vis.is_accessible_from(def_id, self.tcx) { <ins> let label = if in_update_syntax { format!("field `{}` is private", field.ident) } else { "private field".to_string() }; </ins> struct_span_err!( self.tcx.sess, span,


def.variant_descr(), self.tcx.def_path_str(def.did) ) <del> .span_label(span, "private field") </del> <ins> .span_label(span, label) </ins> .emit(); } }