diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 045595ff42785..0276e0433cd4e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -264,6 +264,12 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { bx.lifetime_end(tmp, size); } fx.store_return(bx, ret_dest, &fn_abi.ret, invokeret); + + // If the return value was retagged as it was stored, + // then we might be in a different basic block now. + // Update the cached block for `target` to point to this new + // block, where codegen will continue. + fx.cached_llbbs[target] = CachedLlbb::Some(bx.llbb()); } MergingSucc::False } else { @@ -2186,19 +2192,27 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { llval: Bx::Value, ) { use self::ReturnDest::*; - + let retags_enabled = bx.tcx().sess.opts.unstable_opts.codegen_emit_retag.is_some(); match dest { Nothing => (), - Store(dst) => bx.store_arg(ret_abi, llval, dst), + Store(dst) => { + bx.store_arg(ret_abi, llval, dst); + if retags_enabled { + self.codegen_retag_place(bx, dst, false); + } + } IndirectOperand(tmp, index) => { - let op = bx.load_operand(tmp); + let mut op = bx.load_operand(tmp); tmp.storage_dead(bx); + if retags_enabled { + op = self.codegen_retag_operand(bx, op, false); + } self.overwrite_local(index, LocalRef::Operand(op)); self.debug_introduce_local(bx, index); } DirectOperand(index) => { // If there is a cast, we have to store and reload. - let op = if let PassMode::Cast { .. } = ret_abi.mode { + let mut op = if let PassMode::Cast { .. } = ret_abi.mode { let tmp = PlaceRef::alloca(bx, ret_abi.layout); tmp.storage_live(bx); bx.store_arg(ret_abi, llval, tmp); @@ -2208,6 +2222,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } else { OperandRef::from_immediate_or_packed_pair(bx, llval, ret_abi.layout) }; + if retags_enabled { + op = self.codegen_retag_operand(bx, op, false); + } self.overwrite_local(index, LocalRef::Operand(op)); self.debug_introduce_local(bx, index); } diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 0abdef85b1980..2b6273ef74d6a 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -24,6 +24,7 @@ mod locals; pub mod naked_asm; pub mod operand; pub mod place; +mod retag; mod rvalue; mod statement; @@ -425,7 +426,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( return vec![]; } - let args = mir + let mut args = mir .args_iter() .enumerate() .map(|(arg_index, local)| { @@ -562,6 +563,32 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( } }) .collect::>(); + if bx.tcx().sess.opts.unstable_opts.codegen_emit_retag.is_some() { + args = args + .iter() + .map(|arg| match arg { + &LocalRef::Place(place_ref) => { + fx.codegen_retag_place(bx, place_ref, true); + LocalRef::Place(place_ref) + } + &LocalRef::UnsizedPlace(place_ref) => { + let operand = bx.load_operand(place_ref); + let retagged = fx.codegen_retag_operand(bx, operand, true); + assert!(matches!(retagged.val, OperandValue::Pair(_, _))); + retagged.val.store(bx, place_ref); + LocalRef::UnsizedPlace(place_ref) + } + &LocalRef::Operand(operand_ref) => { + let retagged = fx.codegen_retag_operand(bx, operand_ref, true); + LocalRef::Operand(retagged) + } + LocalRef::PendingOperand => LocalRef::PendingOperand, + }) + .collect::>(); + // If we branched during retagging, then we need to update the + // start block to the new location. + fx.cached_llbbs[mir::START_BLOCK] = CachedLlbb::Some(bx.llbb()); + } if fx.instance.def.requires_caller_location(bx.tcx()) { let mir_args = if let Some(num_untupled) = num_untupled { diff --git a/compiler/rustc_codegen_ssa/src/mir/retag.rs b/compiler/rustc_codegen_ssa/src/mir/retag.rs new file mode 100644 index 0000000000000..a08a434326bb5 --- /dev/null +++ b/compiler/rustc_codegen_ssa/src/mir/retag.rs @@ -0,0 +1,34 @@ +//! Experimental support for emitting retags as function calls in generated code. + +use rustc_middle::mir::{Rvalue, WithRetag}; + +use crate::mir::FunctionCx; +use crate::mir::operand::OperandRef; +use crate::mir::place::PlaceRef; +use crate::traits::BuilderMethods; + +pub(crate) fn rvalue_needs_retag(rvalue: &Rvalue<'_>) -> bool { + // `Ref` has its own internal retagging + !matches!(rvalue, Rvalue::Ref(..)) && !matches!(rvalue, Rvalue::Use(.., WithRetag::No)) +} + +impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { + /// Retags the pointers within an [`OperandRef`]. + pub(crate) fn codegen_retag_operand( + &mut self, + _bx: &mut Bx, + operand: OperandRef<'tcx, Bx::Value>, + _is_fn_entry: bool, + ) -> OperandRef<'tcx, Bx::Value> { + operand + } + + /// Retags the pointers within a [`PlaceRef`]. + pub(crate) fn codegen_retag_place( + &mut self, + _bx: &mut Bx, + _place_ref: PlaceRef<'tcx, Bx::Value>, + _is_fn_entry: bool, + ) { + } +} diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 90ac8c89ba9ad..469d6af12923e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -522,7 +522,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let mk_ref = move |tcx: TyCtxt<'tcx>, ty: Ty<'tcx>| { Ty::new_ref(tcx, tcx.lifetimes.re_erased, ty, bk.to_mutbl_lossy()) }; - self.codegen_place_to_pointer(bx, place, mk_ref) + let op = self.codegen_place_to_pointer(bx, place, mk_ref); + if self.cx.tcx().sess.opts.unstable_opts.codegen_emit_retag.is_some() { + self.codegen_retag_operand(bx, op, false) + } else { + op + } } // Note: Exclusive reborrowing is always equal to a memcpy, as the types do not change. diff --git a/compiler/rustc_codegen_ssa/src/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs index afbef86bd089e..433964218e43b 100644 --- a/compiler/rustc_codegen_ssa/src/mir/statement.rs +++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs @@ -3,6 +3,7 @@ use rustc_middle::{bug, span_bug, ty}; use tracing::instrument; use super::{FunctionCx, LocalRef}; +use crate::mir::retag; use crate::traits::*; impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { @@ -12,9 +13,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.set_debug_loc(bx, statement.source_info); match statement.kind { mir::StatementKind::Assign((ref place, ref rvalue)) => { + let needs_retag = bx.tcx().sess.opts.unstable_opts.codegen_emit_retag.is_some() + && retag::rvalue_needs_retag(rvalue); + if let Some(index) = place.as_local() { match self.locals[index] { - LocalRef::Place(cg_dest) => self.codegen_rvalue(bx, cg_dest, rvalue), + LocalRef::Place(cg_dest) => { + self.codegen_rvalue(bx, cg_dest, rvalue); + if needs_retag { + self.codegen_retag_place(bx, cg_dest, false); + } + } LocalRef::UnsizedPlace(cg_indirect_dest) => { let ty = cg_indirect_dest.layout.ty; span_bug!( @@ -24,7 +33,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ); } LocalRef::PendingOperand => { - let operand = self.codegen_rvalue_operand(bx, rvalue); + let mut operand = self.codegen_rvalue_operand(bx, rvalue); + if needs_retag { + operand = self.codegen_retag_operand(bx, operand, false); + } self.overwrite_local(index, LocalRef::Operand(operand)); self.debug_introduce_local(bx, index); } @@ -39,12 +51,19 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // If the type is zero-sized, it's already been set here, // but we still need to make sure we codegen the operand - self.codegen_rvalue_operand(bx, rvalue); + // and emit a retag. + let operand = self.codegen_rvalue_operand(bx, rvalue); + if needs_retag { + self.codegen_retag_operand(bx, operand, false); + } } } } else { let cg_dest = self.codegen_place(bx, place.as_ref()); self.codegen_rvalue(bx, cg_dest, rvalue); + if needs_retag { + self.codegen_retag_place(bx, cg_dest, false); + } } } mir::StatementKind::SetDiscriminant { ref place, variant_index } => { diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index fc124348a202c..b926f10e1126a 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -10,9 +10,9 @@ use rustc_errors::ColorConfig; use rustc_errors::emitter::HumanReadableErrorType; use rustc_hir::attrs::{CollapseMacroDebuginfo, NativeLibKind}; use rustc_session::config::{ - AnnotateMoves, AutoDiff, BranchProtection, CFGuard, Cfg, CoverageLevel, CoverageOptions, - DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation, Externs, - FmtDebug, FunctionReturn, IncrementalStateAssertion, InliningThreshold, Input, + AnnotateMoves, AutoDiff, BranchProtection, CFGuard, Cfg, CodegenRetagOptions, CoverageLevel, + CoverageOptions, DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation, + Externs, FmtDebug, FunctionReturn, IncrementalStateAssertion, InliningThreshold, Input, InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, MirIncludeSpans, NextSolverConfig, Offload, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, Passes, PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip, @@ -772,6 +772,7 @@ fn test_unstable_options_tracking_hash() { }) ); tracked!(codegen_backend, Some("abc".to_string())); + tracked!(codegen_emit_retag, Some(CodegenRetagOptions::default())); tracked!( coverage_options, CoverageOptions { diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index e82f67eac5e9f..d1ffdd129d53b 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -200,6 +200,15 @@ pub enum Offload { Test, } +/// The different settings that the `-Z codegen-emit-retag` flag can have. +#[derive(Copy, Clone, Debug, Default, PartialEq, Hash, Encodable, Decodable)] +pub struct CodegenRetagOptions { + /// Track interior mutable data on the level of references, instead of on the byte level. + pub no_precise_im: bool, + /// Track `UnsafePinned` data on the level of references, instead of on the byte level. + pub no_precise_pin: bool, +} + /// The different settings that the `-Z autodiff` flag can have. #[derive(Clone, PartialEq, Hash, Debug, Encodable, Decodable)] pub enum AutoDiff { @@ -3045,12 +3054,13 @@ pub(crate) mod dep_tracking { }; use super::{ - AnnotateMoves, AutoDiff, BranchProtection, CFGuard, CFProtection, CoverageOptions, - CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug, FunctionReturn, - InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail, - LtoCli, MirStripDebugInfo, NextSolverConfig, Offload, OptLevel, OutFileName, OutputType, - OutputTypes, PatchableFunctionEntry, Polonius, ResolveDocLinks, SourceFileHashAlgorithm, - SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, + AnnotateMoves, AutoDiff, BranchProtection, CFGuard, CFProtection, CodegenRetagOptions, + CoverageOptions, CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug, + FunctionReturn, InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, + LocationDetail, LtoCli, MirStripDebugInfo, NextSolverConfig, Offload, OptLevel, + OutFileName, OutputType, OutputTypes, PatchableFunctionEntry, Polonius, ResolveDocLinks, + SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, + WasiExecModel, }; use crate::lint; use crate::utils::NativeLib; @@ -3154,6 +3164,7 @@ pub(crate) mod dep_tracking { InliningThreshold, FunctionReturn, Align, + CodegenRetagOptions ); impl DepTrackingHash for (T1, T2) diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 57db7a3eba3b7..c565ecc085583 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -783,6 +783,8 @@ mod desc { pub(crate) const parse_dump_mono_stats: &str = "`markdown` (default) or `json`"; pub(crate) const parse_instrument_coverage: &str = parse_bool; pub(crate) const parse_coverage_options: &str = "`block` | `branch` | `condition`"; + pub(crate) const parse_codegen_retag_options: &str = + "either no value or a comma-separated list of settings: `no-precise-im`, `no-precise-pin`"; pub(crate) const parse_instrument_xray: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), or a comma separated list of settings: `always` or `never` (mutually exclusive), `ignore-loops`, `instruction-threshold=N`, `skip-entry`, `skip-exit`"; pub(crate) const parse_unpretty: &str = "`string` or `string=string`"; pub(crate) const parse_treat_err_as_bug: &str = "either no value or a non-negative number"; @@ -1523,6 +1525,29 @@ pub mod parse { true } + pub(crate) fn parse_codegen_retag_options( + slot: &mut Option, + v: Option<&str>, + ) -> bool { + let mut no_precise_im = false; + let mut no_precise_pin = false; + if let Some(opt_list) = v.map(|s| s.split(',')) { + for opt in opt_list { + match opt { + "no-precise-im" => { + no_precise_im = true; + } + "no-precise-pin" => { + no_precise_pin = true; + } + _ => return false, + } + } + } + *slot = Some(CodegenRetagOptions { no_precise_im, no_precise_pin }); + true + } + pub(crate) fn parse_coverage_options(slot: &mut CoverageOptions, v: Option<&str>) -> bool { let Some(v) = v else { return true }; @@ -2242,6 +2267,8 @@ options! { "hash algorithm of source files used to check freshness in cargo (`blake3` or `sha256`)"), codegen_backend: Option = (None, parse_opt_string, [TRACKED], "the backend to use"), + codegen_emit_retag: Option = (None, parse_codegen_retag_options, [TRACKED], + "emit retag function calls in generated code"), codegen_source_order: bool = (false, parse_bool, [UNTRACKED], "emit mono items in the order of spans in source files (default: no)"), contract_checks: Option = (None, parse_opt_bool, [TRACKED], diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index c83bb62324e76..64818f0114b61 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -553,6 +553,8 @@ impl Session { // HWAddressSanitizer and KernelHWAddressSanitizer will use lifetimes to detect use after // scope bugs in the future. || self.sanitizers().intersects(SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS | SanitizerSet::MEMORY | SanitizerSet::HWADDRESS | SanitizerSet::KERNELHWADDRESS) + // Lifetimes are necessary for retagging semantics. + || self.opts.unstable_opts.codegen_emit_retag.is_some() } pub fn diagnostic_width(&self) -> usize { diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index ed0883ef76e71..68dceb103037e 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -328,7 +328,12 @@ impl<'tcx> LinkCollector<'_, 'tcx> { }) } } - _ => unreachable!(), + _ => Err(UnresolvedPath { + item_id, + module_id, + partial_res: Some(Res::Def(DefKind::TyAlias, did)), + unresolved: variant_name.to_string().into(), + }), } } _ => Err(UnresolvedPath { diff --git a/tests/rustdoc-ui/intra-doc/ty-alias-field.rs b/tests/rustdoc-ui/intra-doc/ty-alias-field.rs new file mode 100644 index 0000000000000..85701ff13c021 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/ty-alias-field.rs @@ -0,0 +1,11 @@ +#![deny(rustdoc::broken_intra_doc_links)] +//~^ NOTE the lint level is defined here + +/// [Self::a::b] +//~^ ERROR unresolved link to `Self::a::b` +//~| NOTE the struct `MyStruct` has no field or associated item named `a` +pub struct MyStruct; +/// [Self::a::b] +//~^ ERROR unresolved link to `Self::a::b` +//~| NOTE the type alias `MyAlias` has no associated item named `a` +pub type MyAlias = MyStruct; diff --git a/tests/rustdoc-ui/intra-doc/ty-alias-field.stderr b/tests/rustdoc-ui/intra-doc/ty-alias-field.stderr new file mode 100644 index 0000000000000..82b38a154dcd4 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/ty-alias-field.stderr @@ -0,0 +1,20 @@ +error: unresolved link to `Self::a::b` + --> $DIR/ty-alias-field.rs:4:6 + | +LL | /// [Self::a::b] + | ^^^^^^^^^^ the struct `MyStruct` has no field or associated item named `a` + | +note: the lint level is defined here + --> $DIR/ty-alias-field.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unresolved link to `Self::a::b` + --> $DIR/ty-alias-field.rs:8:6 + | +LL | /// [Self::a::b] + | ^^^^^^^^^^ the type alias `MyAlias` has no associated item named `a` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/issues/issue-18611.rs b/tests/ui/associated-types/assoc-type-unsatisfied-bound.rs similarity index 71% rename from tests/ui/issues/issue-18611.rs rename to tests/ui/associated-types/assoc-type-unsatisfied-bound.rs index 57da57d83537c..76a93eed7b663 100644 --- a/tests/ui/issues/issue-18611.rs +++ b/tests/ui/associated-types/assoc-type-unsatisfied-bound.rs @@ -1,3 +1,5 @@ +//! Regression test for . + fn add_state(op: ::State) { //~^ ERROR `isize: HasState` is not satisfied //~| ERROR `isize: HasState` is not satisfied diff --git a/tests/ui/issues/issue-18611.stderr b/tests/ui/associated-types/assoc-type-unsatisfied-bound.stderr similarity index 81% rename from tests/ui/issues/issue-18611.stderr rename to tests/ui/associated-types/assoc-type-unsatisfied-bound.stderr index 4fa699de63527..3e318fcac503a 100644 --- a/tests/ui/issues/issue-18611.stderr +++ b/tests/ui/associated-types/assoc-type-unsatisfied-bound.stderr @@ -1,23 +1,23 @@ error[E0277]: the trait bound `isize: HasState` is not satisfied - --> $DIR/issue-18611.rs:1:18 + --> $DIR/assoc-type-unsatisfied-bound.rs:3:18 | LL | fn add_state(op: ::State) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasState` is not implemented for `isize` | help: this trait has no implementations, consider adding one - --> $DIR/issue-18611.rs:6:1 + --> $DIR/assoc-type-unsatisfied-bound.rs:8:1 | LL | trait HasState { | ^^^^^^^^^^^^^^ error[E0277]: the trait bound `isize: HasState` is not satisfied - --> $DIR/issue-18611.rs:1:18 + --> $DIR/assoc-type-unsatisfied-bound.rs:3:18 | LL | fn add_state(op: ::State) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasState` is not implemented for `isize` | help: this trait has no implementations, consider adding one - --> $DIR/issue-18611.rs:6:1 + --> $DIR/assoc-type-unsatisfied-bound.rs:8:1 | LL | trait HasState { | ^^^^^^^^^^^^^^ diff --git a/tests/ui/box/box-deref-match-arm.rs b/tests/ui/box/box-deref-match-arm.rs new file mode 100644 index 0000000000000..621a577afa580 --- /dev/null +++ b/tests/ui/box/box-deref-match-arm.rs @@ -0,0 +1,19 @@ +//! Regression test for . +//! +//! This used to generate invalid IR in that even if we took the +//! `false` branch we'd still try to free the Box from the other +//! arm. This was due to treating `*Box::new(9)` as an rvalue datum +//! instead of as a place. + +//@ run-pass + +fn test(foo: bool) -> u8 { + match foo { + true => *Box::new(9), + false => 0 + } +} + +fn main() { + assert_eq!(9, test(true)); +} diff --git a/tests/ui/issues/auxiliary/issue-18501.rs b/tests/ui/cross-crate/auxiliary/inline-fn-with-trait-method-as-value.rs similarity index 74% rename from tests/ui/issues/auxiliary/issue-18501.rs rename to tests/ui/cross-crate/auxiliary/inline-fn-with-trait-method-as-value.rs index dd914b464fa58..dd90b4a082331 100644 --- a/tests/ui/issues/auxiliary/issue-18501.rs +++ b/tests/ui/cross-crate/auxiliary/inline-fn-with-trait-method-as-value.rs @@ -1,3 +1,5 @@ +//! Auxiliary crate for . + #![crate_type = "rlib"] struct Foo; diff --git a/tests/ui/cross-crate/inline-fn-with-trait-method-as-value.rs b/tests/ui/cross-crate/inline-fn-with-trait-method-as-value.rs new file mode 100644 index 0000000000000..7c68f29352493 --- /dev/null +++ b/tests/ui/cross-crate/inline-fn-with-trait-method-as-value.rs @@ -0,0 +1,15 @@ +//! Regression test for . +//! +//! Test that we don't ICE when inlining a function from another +//! crate that uses a trait method as a value due to incorrectly +//! translating the def ID of the trait during AST decoding. + +//@ run-pass + +//@ aux-build:inline-fn-with-trait-method-as-value.rs + +extern crate inline_fn_with_trait_method_as_value as issue; + +fn main() { + issue::pass_method(); +} diff --git a/tests/ui/issues/issue-18919.rs b/tests/ui/dst/dyn-fn-type-in-generic-enum.rs similarity index 71% rename from tests/ui/issues/issue-18919.rs rename to tests/ui/dst/dyn-fn-type-in-generic-enum.rs index f06771e9ea59d..a4d07b01007dc 100644 --- a/tests/ui/issues/issue-18919.rs +++ b/tests/ui/dst/dyn-fn-type-in-generic-enum.rs @@ -1,3 +1,5 @@ +//! Regression test for . + type FuncType<'f> = dyn Fn(&isize) -> isize + 'f; fn ho_func(f: Option) { diff --git a/tests/ui/issues/issue-18919.stderr b/tests/ui/dst/dyn-fn-type-in-generic-enum.stderr similarity index 86% rename from tests/ui/issues/issue-18919.stderr rename to tests/ui/dst/dyn-fn-type-in-generic-enum.stderr index 714b6d7d86be3..dc672399e6800 100644 --- a/tests/ui/issues/issue-18919.stderr +++ b/tests/ui/dst/dyn-fn-type-in-generic-enum.stderr @@ -1,17 +1,17 @@ error[E0277]: the size for values of type `dyn for<'a> Fn(&'a isize) -> isize` cannot be known at compilation time - --> $DIR/issue-18919.rs:3:15 + --> $DIR/dyn-fn-type-in-generic-enum.rs:5:15 | LL | fn ho_func(f: Option) { | ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `dyn for<'a> Fn(&'a isize) -> isize` note: required by an implicit `Sized` bound in `Option` - --> $DIR/issue-18919.rs:7:13 + --> $DIR/dyn-fn-type-in-generic-enum.rs:9:13 | LL | enum Option { | ^ required by the implicit `Sized` requirement on this type parameter in `Option` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` - --> $DIR/issue-18919.rs:7:13 + --> $DIR/dyn-fn-type-in-generic-enum.rs:9:13 | LL | enum Option { | ^ this could be changed to `T: ?Sized`... diff --git a/tests/ui/issues/issue-18959.rs b/tests/ui/dyn-compatibility/dyn-incompatible-supertrait.rs similarity index 83% rename from tests/ui/issues/issue-18959.rs rename to tests/ui/dyn-compatibility/dyn-incompatible-supertrait.rs index 415fe818f5308..90a30e7920544 100644 --- a/tests/ui/issues/issue-18959.rs +++ b/tests/ui/dyn-compatibility/dyn-incompatible-supertrait.rs @@ -1,3 +1,5 @@ +//! Regression test for . + pub trait Foo { fn foo(&self, ext_thing: &T); } pub trait Bar: Foo { } impl Bar for T { } diff --git a/tests/ui/issues/issue-18959.stderr b/tests/ui/dyn-compatibility/dyn-incompatible-supertrait.stderr similarity index 87% rename from tests/ui/issues/issue-18959.stderr rename to tests/ui/dyn-compatibility/dyn-incompatible-supertrait.stderr index df47d50a01979..34f1ed729c135 100644 --- a/tests/ui/issues/issue-18959.stderr +++ b/tests/ui/dyn-compatibility/dyn-incompatible-supertrait.stderr @@ -1,12 +1,12 @@ error[E0038]: the trait `Bar` is not dyn compatible - --> $DIR/issue-18959.rs:11:12 + --> $DIR/dyn-incompatible-supertrait.rs:13:12 | LL | fn foo(b: &dyn Bar) { | ^^^^^^^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit - --> $DIR/issue-18959.rs:1:20 + --> $DIR/dyn-incompatible-supertrait.rs:3:20 | LL | pub trait Foo { fn foo(&self, ext_thing: &T); } | ^^^ ...because method `foo` has generic type parameters @@ -15,14 +15,14 @@ LL | pub trait Bar: Foo { } = help: consider moving `foo` to another trait error[E0038]: the trait `Bar` is not dyn compatible - --> $DIR/issue-18959.rs:18:20 + --> $DIR/dyn-incompatible-supertrait.rs:20:20 | LL | let test: &dyn Bar = &mut thing; | ^^^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit - --> $DIR/issue-18959.rs:1:20 + --> $DIR/dyn-incompatible-supertrait.rs:3:20 | LL | pub trait Foo { fn foo(&self, ext_thing: &T); } | ^^^ ...because method `foo` has generic type parameters @@ -31,14 +31,14 @@ LL | pub trait Bar: Foo { } = help: consider moving `foo` to another trait error[E0038]: the trait `Bar` is not dyn compatible - --> $DIR/issue-18959.rs:20:9 + --> $DIR/dyn-incompatible-supertrait.rs:22:9 | LL | foo(test); | ^^^^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit - --> $DIR/issue-18959.rs:1:20 + --> $DIR/dyn-incompatible-supertrait.rs:3:20 | LL | pub trait Foo { fn foo(&self, ext_thing: &T); } | ^^^ ...because method `foo` has generic type parameters diff --git a/tests/ui/issues/auxiliary/issue-18711.rs b/tests/ui/issues/auxiliary/issue-18711.rs deleted file mode 100644 index 5cb1f9c43718e..0000000000000 --- a/tests/ui/issues/auxiliary/issue-18711.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![crate_type = "rlib"] - -pub fn inner(f: F) -> F { - (move || f)() -} diff --git a/tests/ui/issues/issue-18501.rs b/tests/ui/issues/issue-18501.rs deleted file mode 100644 index 54e53e434c465..0000000000000 --- a/tests/ui/issues/issue-18501.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ run-pass -// Test that we don't ICE when inlining a function from another -// crate that uses a trait method as a value due to incorrectly -// translating the def ID of the trait during AST decoding. - -//@ aux-build:issue-18501.rs - -extern crate issue_18501 as issue; - -fn main() { - issue::pass_method(); -} diff --git a/tests/ui/issues/issue-18711.rs b/tests/ui/issues/issue-18711.rs deleted file mode 100644 index 1d5e3349a6d42..0000000000000 --- a/tests/ui/issues/issue-18711.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ run-pass -// Test that we don't panic on a RefCell borrow conflict in certain -// code paths involving unboxed closures. - - -//@ aux-build:issue-18711.rs -extern crate issue_18711 as issue; - -fn main() { - (|| issue::inner(()))(); -} diff --git a/tests/ui/issues/issue-18845.rs b/tests/ui/issues/issue-18845.rs deleted file mode 100644 index c9dc175b10a8a..0000000000000 --- a/tests/ui/issues/issue-18845.rs +++ /dev/null @@ -1,16 +0,0 @@ -//@ run-pass -// This used to generate invalid IR in that even if we took the -// `false` branch we'd still try to free the Box from the other -// arm. This was due to treating `*Box::new(9)` as an rvalue datum -// instead of as a place. - -fn test(foo: bool) -> u8 { - match foo { - true => *Box::new(9), - false => 0 - } -} - -fn main() { - assert_eq!(9, test(true)); -} diff --git a/tests/ui/issues/issue-18859.rs b/tests/ui/issues/issue-18859.rs deleted file mode 100644 index 854b7ed62f05b..0000000000000 --- a/tests/ui/issues/issue-18859.rs +++ /dev/null @@ -1,16 +0,0 @@ -//@ run-pass - -mod foo { - pub mod bar { - pub mod baz { - pub fn name() -> &'static str { - module_path!() - } - } - } -} - -fn main() { - assert_eq!(module_path!(), "issue_18859"); - assert_eq!(foo::bar::baz::name(), "issue_18859::foo::bar::baz"); -} diff --git a/tests/ui/issues/issue-18913.rs b/tests/ui/issues/issue-18913.rs deleted file mode 100644 index 7f9137d95c24f..0000000000000 --- a/tests/ui/issues/issue-18913.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ run-pass -//@ aux-build:issue-18913-1.rs -//@ aux-build:issue-18913-2.rs - -extern crate foo; - -fn main() { - assert_eq!(foo::foo(), 1); -} diff --git a/tests/ui/issues/auxiliary/issue-18913-1.rs b/tests/ui/linking/auxiliary/duplicate-rlib-crate-name-precedence-1.rs similarity index 56% rename from tests/ui/issues/auxiliary/issue-18913-1.rs rename to tests/ui/linking/auxiliary/duplicate-rlib-crate-name-precedence-1.rs index caa2c707b560d..7b2bfbba12e6e 100644 --- a/tests/ui/issues/auxiliary/issue-18913-1.rs +++ b/tests/ui/linking/auxiliary/duplicate-rlib-crate-name-precedence-1.rs @@ -1,3 +1,5 @@ +//! Auxiliary crate for . + //@ no-prefer-dynamic #![crate_type = "rlib"] diff --git a/tests/ui/issues/auxiliary/issue-18913-2.rs b/tests/ui/linking/auxiliary/duplicate-rlib-crate-name-precedence-2.rs similarity index 56% rename from tests/ui/issues/auxiliary/issue-18913-2.rs rename to tests/ui/linking/auxiliary/duplicate-rlib-crate-name-precedence-2.rs index 802f5ab3899bb..fc0d3d6ea4283 100644 --- a/tests/ui/issues/auxiliary/issue-18913-2.rs +++ b/tests/ui/linking/auxiliary/duplicate-rlib-crate-name-precedence-2.rs @@ -1,3 +1,5 @@ +//! Auxiliary crate for . + //@ no-prefer-dynamic #![crate_type = "rlib"] diff --git a/tests/ui/linking/duplicate-rlib-crate-name-precedence.rs b/tests/ui/linking/duplicate-rlib-crate-name-precedence.rs new file mode 100644 index 0000000000000..5131df3903423 --- /dev/null +++ b/tests/ui/linking/duplicate-rlib-crate-name-precedence.rs @@ -0,0 +1,11 @@ +//! Regression test for . + +//@ run-pass +//@ aux-build:duplicate-rlib-crate-name-precedence-1.rs +//@ aux-build:duplicate-rlib-crate-name-precedence-2.rs + +extern crate foo; + +fn main() { + assert_eq!(foo::foo(), 1); +} diff --git a/tests/ui/macros/module-path-in-nested-modules.rs b/tests/ui/macros/module-path-in-nested-modules.rs new file mode 100644 index 0000000000000..601599e92943e --- /dev/null +++ b/tests/ui/macros/module-path-in-nested-modules.rs @@ -0,0 +1,18 @@ +//! Regression test for . + +//@ run-pass + +mod foo { + pub mod bar { + pub mod baz { + pub fn name() -> &'static str { + module_path!() + } + } + } +} + +fn main() { + assert_eq!(module_path!(), "module_path_in_nested_modules"); + assert_eq!(foo::bar::baz::name(), "module_path_in_nested_modules::foo::bar::baz"); +} diff --git a/tests/ui/issues/issue-18988.rs b/tests/ui/traits/object/trait-object-with-send-supertrait.rs similarity index 67% rename from tests/ui/issues/issue-18988.rs rename to tests/ui/traits/object/trait-object-with-send-supertrait.rs index 9dffe5640809a..cbdc8693708c9 100644 --- a/tests/ui/issues/issue-18988.rs +++ b/tests/ui/traits/object/trait-object-with-send-supertrait.rs @@ -1,3 +1,5 @@ +//! Regression test for . + //@ check-pass #![allow(dead_code)] pub trait Foo : Send { } diff --git a/tests/ui/unboxed-closures/auxiliary/cross-crate-generic-fn-in-closure.rs b/tests/ui/unboxed-closures/auxiliary/cross-crate-generic-fn-in-closure.rs new file mode 100644 index 0000000000000..06cd968caff1e --- /dev/null +++ b/tests/ui/unboxed-closures/auxiliary/cross-crate-generic-fn-in-closure.rs @@ -0,0 +1,7 @@ +//! Auxiliary crate for . + +#![crate_type = "rlib"] + +pub fn inner(f: F) -> F { + (move || f)() +} diff --git a/tests/ui/unboxed-closures/cross-crate-generic-fn-in-closure.rs b/tests/ui/unboxed-closures/cross-crate-generic-fn-in-closure.rs new file mode 100644 index 0000000000000..5c943721103e6 --- /dev/null +++ b/tests/ui/unboxed-closures/cross-crate-generic-fn-in-closure.rs @@ -0,0 +1,12 @@ +//! Regression test for . +//! Test that we don't panic on a RefCell borrow conflict in certain +//! code paths involving unboxed closures. + +//@ run-pass + +//@ aux-build:cross-crate-generic-fn-in-closure.rs +extern crate cross_crate_generic_fn_in_closure as issue; + +fn main() { + (|| issue::inner(()))(); +} diff --git a/tests/ui/issues/issue-18906.rs b/tests/ui/where-clauses/impl-method-where-clause-resolution.rs similarity index 87% rename from tests/ui/issues/issue-18906.rs rename to tests/ui/where-clauses/impl-method-where-clause-resolution.rs index 84b0f5a178825..af2bf63ad106a 100644 --- a/tests/ui/issues/issue-18906.rs +++ b/tests/ui/where-clauses/impl-method-where-clause-resolution.rs @@ -1,3 +1,5 @@ +//! Regression test for . + //@ check-pass #![allow(dead_code)]