diff --git a/src/librustc_middle/arena.rs b/src/librustc_middle/arena.rs index a97db3134dc9e..2df878c3fb220 100644 --- a/src/librustc_middle/arena.rs +++ b/src/librustc_middle/arena.rs @@ -76,6 +76,12 @@ macro_rules! arena_types { [few] hir_definitions: rustc_hir::definitions::Definitions, [] hir_owner: rustc_middle::hir::Owner<$tcx>, [] hir_owner_nodes: rustc_middle::hir::OwnerNodes<$tcx>, + + // Note that this deliberately duplicates items in the `rustc_hir::arena`, + // since we need to allocate this type on both the `rustc_hir` arena + // (during lowering) and the `librustc_middle` arena (for decoding MIR) + [decode] asm_template: rustc_ast::ast::InlineAsmTemplatePiece, + ], $tcx); ) } diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 5f8104e7934eb..50a882ab014fd 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -266,7 +266,7 @@ impl TransformVisitor<'tcx> { // Create a statement which reads the discriminant into a temporary fn get_discr(&self, body: &mut Body<'tcx>) -> (Statement<'tcx>, Place<'tcx>) { - let temp_decl = LocalDecl::new(self.tcx.types.isize, body.span).internal(); + let temp_decl = LocalDecl::new(self.discr_ty, body.span).internal(); let local_decls_len = body.local_decls.push(temp_decl); let temp = Place::from(local_decls_len); diff --git a/src/librustc_target/asm/mod.rs b/src/librustc_target/asm/mod.rs index 05aa85ecb7448..774146a679ab8 100644 --- a/src/librustc_target/asm/mod.rs +++ b/src/librustc_target/asm/mod.rs @@ -223,19 +223,19 @@ impl InlineAsmReg { name: Symbol, ) -> Result { // FIXME: use direct symbol comparison for register names - name.with(|name| { - Ok(match arch { - InlineAsmArch::X86 | InlineAsmArch::X86_64 => { - Self::X86(X86InlineAsmReg::parse(arch, has_feature, name)?) - } - InlineAsmArch::Arm => Self::Arm(ArmInlineAsmReg::parse(arch, has_feature, name)?), - InlineAsmArch::AArch64 => { - Self::AArch64(AArch64InlineAsmReg::parse(arch, has_feature, name)?) - } - InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => { - Self::RiscV(RiscVInlineAsmReg::parse(arch, has_feature, name)?) - } - }) + // Use `Symbol::as_str` instead of `Symbol::with` here because `has_feature` may access `Symbol`. + let name = name.as_str(); + Ok(match arch { + InlineAsmArch::X86 | InlineAsmArch::X86_64 => { + Self::X86(X86InlineAsmReg::parse(arch, has_feature, &name)?) + } + InlineAsmArch::Arm => Self::Arm(ArmInlineAsmReg::parse(arch, has_feature, &name)?), + InlineAsmArch::AArch64 => { + Self::AArch64(AArch64InlineAsmReg::parse(arch, has_feature, &name)?) + } + InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => { + Self::RiscV(RiscVInlineAsmReg::parse(arch, has_feature, &name)?) + } }) } diff --git a/src/librustc_trait_selection/traits/error_reporting/mod.rs b/src/librustc_trait_selection/traits/error_reporting/mod.rs index 2aef8aaf0e303..b1c6815c7414f 100644 --- a/src/librustc_trait_selection/traits/error_reporting/mod.rs +++ b/src/librustc_trait_selection/traits/error_reporting/mod.rs @@ -1000,12 +1000,15 @@ trait InferCtxtPrivExt<'tcx> { trait_ref: &ty::PolyTraitRef<'tcx>, ); - fn mk_obligation_for_def_id( + /// Creates a `PredicateObligation` with `new_self_ty` replacing the existing type in the + /// `trait_ref`. + /// + /// For this to work, `new_self_ty` must have no escaping bound variables. + fn mk_trait_obligation_with_new_self_ty( &self, - def_id: DefId, - output_ty: Ty<'tcx>, - cause: ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, + trait_ref: &ty::PolyTraitRef<'tcx>, + new_self_ty: Ty<'tcx>, ) -> PredicateObligation<'tcx>; fn maybe_report_ambiguity( @@ -1380,16 +1383,24 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { } } - fn mk_obligation_for_def_id( + fn mk_trait_obligation_with_new_self_ty( &self, - def_id: DefId, - output_ty: Ty<'tcx>, - cause: ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, + trait_ref: &ty::PolyTraitRef<'tcx>, + new_self_ty: Ty<'tcx>, ) -> PredicateObligation<'tcx> { - let new_trait_ref = - ty::TraitRef { def_id, substs: self.tcx.mk_substs_trait(output_ty, &[]) }; - Obligation::new(cause, param_env, new_trait_ref.without_const().to_predicate(self.tcx)) + assert!(!new_self_ty.has_escaping_bound_vars()); + + let trait_ref = trait_ref.map_bound_ref(|tr| ty::TraitRef { + substs: self.tcx.mk_substs_trait(new_self_ty, &tr.substs[1..]), + ..*tr + }); + + Obligation::new( + ObligationCause::dummy(), + param_env, + trait_ref.without_const().to_predicate(self.tcx), + ) } fn maybe_report_ambiguity( diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs index 50a59469d8530..5c85855535e38 100644 --- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs +++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs @@ -532,14 +532,17 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { }; let msg = format!("use parentheses to call the {}", callable); - let obligation = self.mk_obligation_for_def_id( - trait_ref.def_id(), - output_ty.skip_binder(), - obligation.cause.clone(), - obligation.param_env, - ); + // `mk_trait_obligation_with_new_self_ty` only works for types with no escaping bound + // variables, so bail out if we have any. + let output_ty = match output_ty.no_bound_vars() { + Some(ty) => ty, + None => return, + }; + + let new_obligation = + self.mk_trait_obligation_with_new_self_ty(obligation.param_env, trait_ref, output_ty); - match self.evaluate_obligation(&obligation) { + match self.evaluate_obligation(&new_obligation) { Ok( EvaluationResult::EvaluatedToOk | EvaluationResult::EvaluatedToOkModuloRegions @@ -694,7 +697,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { err: &mut DiagnosticBuilder<'_>, trait_ref: &ty::Binder>, ) { - let trait_ref = trait_ref.skip_binder(); let span = obligation.cause.span; if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { @@ -705,17 +707,16 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { return; } - let mut trait_type = trait_ref.self_ty(); + let mut suggested_ty = trait_ref.self_ty(); for refs_remaining in 0..refs_number { - if let ty::Ref(_, t_type, _) = trait_type.kind { - trait_type = t_type; + if let ty::Ref(_, inner_ty, _) = suggested_ty.kind { + suggested_ty = inner_ty; - let new_obligation = self.mk_obligation_for_def_id( - trait_ref.def_id, - trait_type, - ObligationCause::dummy(), + let new_obligation = self.mk_trait_obligation_with_new_self_ty( obligation.param_env, + trait_ref, + suggested_ty, ); if self.predicate_may_hold(&new_obligation) { @@ -782,20 +783,20 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { return; } - let trait_type = match mutability { + let suggested_ty = match mutability { hir::Mutability::Mut => self.tcx.mk_imm_ref(region, t_type), hir::Mutability::Not => self.tcx.mk_mut_ref(region, t_type), }; - let new_obligation = self.mk_obligation_for_def_id( - trait_ref.skip_binder().def_id, - trait_type, - ObligationCause::dummy(), + let new_obligation = self.mk_trait_obligation_with_new_self_ty( obligation.param_env, + &trait_ref, + suggested_ty, ); - - if self.evaluate_obligation_no_overflow(&new_obligation).must_apply_modulo_regions() - { + let suggested_ty_would_satisfy_obligation = self + .evaluate_obligation_no_overflow(&new_obligation) + .must_apply_modulo_regions(); + if suggested_ty_would_satisfy_obligation { let sp = self .tcx .sess @@ -812,7 +813,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { err.note(&format!( "`{}` is implemented for `{:?}`, but not for `{:?}`", trait_ref.print_only_trait_path(), - trait_type, + suggested_ty, trait_ref.skip_binder().self_ty(), )); } @@ -1891,7 +1892,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { span: Span, ) { debug!( - "suggest_await_befor_try: obligation={:?}, span={:?}, trait_ref={:?}, trait_ref_self_ty={:?}", + "suggest_await_before_try: obligation={:?}, span={:?}, trait_ref={:?}, trait_ref_self_ty={:?}", obligation, span, trait_ref, @@ -1946,16 +1947,15 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ); debug!( - "suggest_await_befor_try: normalized_projection_type {:?}", + "suggest_await_before_try: normalized_projection_type {:?}", self.resolve_vars_if_possible(&normalized_ty) ); - let try_obligation = self.mk_obligation_for_def_id( - trait_ref.def_id(), - normalized_ty, - obligation.cause.clone(), + let try_obligation = self.mk_trait_obligation_with_new_self_ty( obligation.param_env, + trait_ref, + normalized_ty, ); - debug!("suggest_await_befor_try: try_trait_obligation {:?}", try_obligation); + debug!("suggest_await_before_try: try_trait_obligation {:?}", try_obligation); if self.predicate_may_hold(&try_obligation) && impls_future { if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { if snippet.ends_with('?') { diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 2cb3347135c1b..b1e0ab9ca64fd 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -3,12 +3,14 @@ font-family: 'Fira Sans'; font-style: normal; font-weight: 400; + font-display: optional; src: local('Fira Sans'), url("FiraSans-Regular.woff") format('woff'); } @font-face { font-family: 'Fira Sans'; font-style: normal; font-weight: 500; + font-display: optional; src: local('Fira Sans Medium'), url("FiraSans-Medium.woff") format('woff'); } @@ -17,18 +19,23 @@ font-family: 'Source Serif Pro'; font-style: normal; font-weight: 400; + /* The difference for body text without this font is greater than other fonts, + * so the 0~100ms block of fallback is preferred over optional, for legibility. */ + font-display: fallback; src: local('Source Serif Pro'), url("SourceSerifPro-Regular.ttf.woff") format('woff'); } @font-face { font-family: 'Source Serif Pro'; font-style: italic; font-weight: 400; + font-display: optional; src: local('Source Serif Pro Italic'), url("SourceSerifPro-It.ttf.woff") format('woff'); } @font-face { font-family: 'Source Serif Pro'; font-style: normal; font-weight: 700; + font-display: optional; src: local('Source Serif Pro Bold'), url("SourceSerifPro-Bold.ttf.woff") format('woff'); } @@ -37,6 +44,7 @@ font-family: 'Source Code Pro'; font-style: normal; font-weight: 400; + font-display: optional; /* Avoid using locally installed font because bad versions are in circulation: * see https://github.com/rust-lang/rust/issues/24355 */ src: url("SourceCodePro-Regular.woff") format('woff'); @@ -45,6 +53,7 @@ font-family: 'Source Code Pro'; font-style: normal; font-weight: 600; + font-display: optional; src: url("SourceCodePro-Semibold.woff") format('woff'); } diff --git a/src/test/incremental/issue-72386.rs b/src/test/incremental/issue-72386.rs new file mode 100644 index 0000000000000..3dc7f502a5992 --- /dev/null +++ b/src/test/incremental/issue-72386.rs @@ -0,0 +1,22 @@ +// revisions: rpass1 cfail1 rpass3 +// only-x86_64 +// Regression test for issue #72386 +// Checks that we don't ICE when switching to an invalid register +// and back again + +#![feature(asm)] + +#[cfg(any(rpass1, rpass3))] +fn main() { + unsafe { + asm!("nop") + } +} + +#[cfg(cfail1)] +fn main() { + unsafe { + asm!("nop",out("invalid_reg")_) + //[cfail1]~^ ERROR invalid register + } +} diff --git a/src/test/mir-opt/generator-drop-cleanup/rustc.main-{{closure}}.generator_drop.0.mir b/src/test/mir-opt/generator-drop-cleanup/rustc.main-{{closure}}.generator_drop.0.mir index 382273a1e73e3..6a32a42d85a82 100644 --- a/src/test/mir-opt/generator-drop-cleanup/rustc.main-{{closure}}.generator_drop.0.mir +++ b/src/test/mir-opt/generator-drop-cleanup/rustc.main-{{closure}}.generator_drop.0.mir @@ -9,7 +9,7 @@ fn main::{{closure}}#0(_1: *mut [generator@$DIR/generator-drop-cleanup.rs:10:15: let mut _5: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:12:9: 12:14 let mut _7: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:10:18: 10:18 let mut _8: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:10:15: 13:6 - let mut _9: isize; // in scope 0 at $DIR/generator-drop-cleanup.rs:10:15: 13:6 + let mut _9: u32; // in scope 0 at $DIR/generator-drop-cleanup.rs:10:15: 13:6 scope 1 { debug _s => (((*_1) as variant#3).0: std::string::String); // in scope 1 at $DIR/generator-drop-cleanup.rs:11:13: 11:15 } diff --git a/src/test/mir-opt/generator-tiny/rustc.main-{{closure}}.generator_resume.0.mir b/src/test/mir-opt/generator-tiny/rustc.main-{{closure}}.generator_resume.0.mir index 75c2fb3d1307d..c73dea5f8fde6 100644 --- a/src/test/mir-opt/generator-tiny/rustc.main-{{closure}}.generator_resume.0.mir +++ b/src/test/mir-opt/generator-tiny/rustc.main-{{closure}}.generator_resume.0.mir @@ -12,7 +12,7 @@ fn main::{{closure}}#0(_1: std::pin::Pin<&mut [generator@$DIR/generator-tiny.rs: let _8: (); // in scope 0 at $DIR/generator-tiny.rs:23:13: 23:21 let mut _9: (); // in scope 0 at $DIR/generator-tiny.rs:19:25: 19:25 let _10: u8; // in scope 0 at $DIR/generator-tiny.rs:19:17: 19:19 - let mut _11: isize; // in scope 0 at $DIR/generator-tiny.rs:19:16: 25:6 + let mut _11: u32; // in scope 0 at $DIR/generator-tiny.rs:19:16: 25:6 scope 1 { debug _d => (((*(_1.0: &mut [generator@$DIR/generator-tiny.rs:19:16: 25:6 {u8, HasDrop, ()}])) as variant#3).0: HasDrop); // in scope 1 at $DIR/generator-tiny.rs:20:13: 20:15 } diff --git a/src/test/ui/suggestions/into-str.stderr b/src/test/ui/suggestions/into-str.stderr index 7414a7cc24c92..f7affdbf1b408 100644 --- a/src/test/ui/suggestions/into-str.stderr +++ b/src/test/ui/suggestions/into-str.stderr @@ -8,7 +8,6 @@ LL | foo(String::new()); | ^^^ the trait `std::convert::From` is not implemented for `&str` | = note: to coerce a `std::string::String` into a `&str`, use `&*` as a prefix - = note: `std::convert::From` is implemented for `&mut str`, but not for `&str` = note: required because of the requirements on the impl of `std::convert::Into<&str>` for `std::string::String` error: aborting due to previous error diff --git a/src/test/ui/suggestions/issue-71394-no-from-impl.rs b/src/test/ui/suggestions/issue-71394-no-from-impl.rs new file mode 100644 index 0000000000000..9ffcc3f7bc1c1 --- /dev/null +++ b/src/test/ui/suggestions/issue-71394-no-from-impl.rs @@ -0,0 +1,5 @@ +fn main() { + let data: &[u8] = &[0; 10]; + let _: &[i8] = data.into(); + //~^ ERROR the trait bound `&[i8]: std::convert::From<&[u8]>` is not satisfied +} diff --git a/src/test/ui/suggestions/issue-71394-no-from-impl.stderr b/src/test/ui/suggestions/issue-71394-no-from-impl.stderr new file mode 100644 index 0000000000000..84c73c2f67e70 --- /dev/null +++ b/src/test/ui/suggestions/issue-71394-no-from-impl.stderr @@ -0,0 +1,11 @@ +error[E0277]: the trait bound `&[i8]: std::convert::From<&[u8]>` is not satisfied + --> $DIR/issue-71394-no-from-impl.rs:3:25 + | +LL | let _: &[i8] = data.into(); + | ^^^^ the trait `std::convert::From<&[u8]>` is not implemented for `&[i8]` + | + = note: required because of the requirements on the impl of `std::convert::Into<&[i8]>` for `&[u8]` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`.