Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 72fdf91

Browse files
committedJun 5, 2024
Auto merge of rust-lang#126038 - matthiaskrgr:rollup-h4rm3x2, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - rust-lang#124840 (resolve: mark it undetermined if single import is not has any bindings) - rust-lang#125622 (Winnow private method candidates instead of assuming any candidate of the right name will apply) - rust-lang#125648 (Remove unused(?) `~/rustsrc` folder from docker script) - rust-lang#125672 (Add more ABI test cases to miri (RFC 3391)) - rust-lang#125800 (Fix `mut` static task queue in SGX target) - rust-lang#125871 (Orphanck[old solver]: Consider opaque types to never cover type parameters) - rust-lang#125893 (Handle all GVN binops in a single place.) - rust-lang#126008 (Port `tests/run-make-fulldeps/issue-19371` to ui-fulldeps) - rust-lang#126032 (Update description of the `IsTerminal` example) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 7ebd2bd + fa58891 commit 72fdf91

37 files changed

+455
-190
lines changed
 

‎compiler/rustc_const_eval/src/interpret/terminator.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -294,17 +294,30 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
294294

295295
/// Unwrap types that are guaranteed a null-pointer-optimization
296296
fn unfold_npo(&self, layout: TyAndLayout<'tcx>) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
297-
// Check if this is `Option` wrapping some type.
298-
let inner = match layout.ty.kind() {
299-
ty::Adt(def, args) if self.tcx.is_diagnostic_item(sym::Option, def.did()) => {
300-
args[0].as_type().unwrap()
301-
}
302-
_ => {
303-
// Not an `Option`.
304-
return Ok(layout);
297+
// Check if this is `Option` wrapping some type or if this is `Result` wrapping a 1-ZST and
298+
// another type.
299+
let ty::Adt(def, args) = layout.ty.kind() else {
300+
// Not an ADT, so definitely no NPO.
301+
return Ok(layout);
302+
};
303+
let inner = if self.tcx.is_diagnostic_item(sym::Option, def.did()) {
304+
// The wrapped type is the only arg.
305+
self.layout_of(args[0].as_type().unwrap())?
306+
} else if self.tcx.is_diagnostic_item(sym::Result, def.did()) {
307+
// We want to extract which (if any) of the args is not a 1-ZST.
308+
let lhs = self.layout_of(args[0].as_type().unwrap())?;
309+
let rhs = self.layout_of(args[1].as_type().unwrap())?;
310+
if lhs.is_1zst() {
311+
rhs
312+
} else if rhs.is_1zst() {
313+
lhs
314+
} else {
315+
return Ok(layout); // no NPO
305316
}
317+
} else {
318+
return Ok(layout); // no NPO
306319
};
307-
let inner = self.layout_of(inner)?;
320+
308321
// Check if the inner type is one of the NPO-guaranteed ones.
309322
// For that we first unpeel transparent *structs* (but not unions).
310323
let is_npo = |def: AdtDef<'tcx>| {

‎compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,7 +1066,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10661066
ty::ImplContainer => {
10671067
if segments.len() == 1 {
10681068
// `<T>::assoc` will end up here, and so
1069-
// can `T::assoc`. It this came from an
1069+
// can `T::assoc`. If this came from an
10701070
// inherent impl, we need to record the
10711071
// `T` for posterity (see `UserSelfTy` for
10721072
// details).
@@ -1416,11 +1416,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14161416
) {
14171417
Ok(ok) => self.register_infer_ok_obligations(ok),
14181418
Err(_) => {
1419-
self.dcx().span_delayed_bug(
1419+
self.dcx().span_bug(
14201420
span,
14211421
format!(
1422-
"instantiate_value_path: (UFCS) {self_ty:?} was a subtype of {impl_ty:?} but now is not?",
1423-
),
1422+
"instantiate_value_path: (UFCS) {self_ty:?} was a subtype of {impl_ty:?} but now is not?",
1423+
),
14241424
);
14251425
}
14261426
}

‎compiler/rustc_hir_typeck/src/method/probe.rs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ use rustc_trait_selection::traits::query::method_autoderef::{
4141
use rustc_trait_selection::traits::query::CanonicalTyGoal;
4242
use rustc_trait_selection::traits::ObligationCtxt;
4343
use rustc_trait_selection::traits::{self, ObligationCause};
44+
use std::cell::Cell;
4445
use std::cell::RefCell;
4546
use std::cmp::max;
4647
use std::iter;
@@ -76,8 +77,12 @@ pub(crate) struct ProbeContext<'a, 'tcx> {
7677
/// requested name (by edit distance)
7778
allow_similar_names: bool,
7879

80+
/// List of potential private candidates. Will be trimmed to ones that
81+
/// actually apply and then the result inserted into `private_candidate`
82+
private_candidates: Vec<Candidate<'tcx>>,
83+
7984
/// Some(candidate) if there is a private candidate
80-
private_candidate: Option<(DefKind, DefId)>,
85+
private_candidate: Cell<Option<(DefKind, DefId)>>,
8186

8287
/// Collects near misses when the candidate functions are missing a `self` keyword and is only
8388
/// used for error reporting
@@ -581,7 +586,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
581586
orig_steps_var_values,
582587
steps,
583588
allow_similar_names: false,
584-
private_candidate: None,
589+
private_candidates: Vec::new(),
590+
private_candidate: Cell::new(None),
585591
static_candidates: RefCell::new(Vec::new()),
586592
unsatisfied_predicates: RefCell::new(Vec::new()),
587593
scope_expr_id,
@@ -593,7 +599,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
593599
self.inherent_candidates.clear();
594600
self.extension_candidates.clear();
595601
self.impl_dups.clear();
596-
self.private_candidate = None;
602+
self.private_candidates.clear();
603+
self.private_candidate.set(None);
597604
self.static_candidates.borrow_mut().clear();
598605
self.unsatisfied_predicates.borrow_mut().clear();
599606
}
@@ -617,9 +624,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
617624
} else {
618625
self.extension_candidates.push(candidate);
619626
}
620-
} else if self.private_candidate.is_none() {
621-
self.private_candidate =
622-
Some((candidate.item.kind.as_def_kind(), candidate.item.def_id));
627+
} else {
628+
self.private_candidates.push(candidate);
623629
}
624630
}
625631

@@ -1171,7 +1177,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
11711177
let mut possibly_unsatisfied_predicates = Vec::new();
11721178

11731179
for (kind, candidates) in
1174-
&[("inherent", &self.inherent_candidates), ("extension", &self.extension_candidates)]
1180+
[("inherent", &self.inherent_candidates), ("extension", &self.extension_candidates)]
11751181
{
11761182
debug!("searching {} candidates", kind);
11771183
let res = self.consider_candidates(
@@ -1185,6 +1191,14 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
11851191
}
11861192
}
11871193

1194+
if self.private_candidate.get().is_none() {
1195+
if let Some(Ok(pick)) =
1196+
self.consider_candidates(self_ty, &self.private_candidates, &mut vec![], None)
1197+
{
1198+
self.private_candidate.set(Some((pick.item.kind.as_def_kind(), pick.item.def_id)));
1199+
}
1200+
}
1201+
11881202
// `pick_method` may be called twice for the same self_ty if no stable methods
11891203
// match. Only extend once.
11901204
if unstable_candidates.is_some() {

‎compiler/rustc_mir_transform/src/gvn.rs

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,6 @@ enum Value<'tcx> {
223223
NullaryOp(NullOp<'tcx>, Ty<'tcx>),
224224
UnaryOp(UnOp, VnIndex),
225225
BinaryOp(BinOp, VnIndex, VnIndex),
226-
CheckedBinaryOp(BinOp, VnIndex, VnIndex), // FIXME get rid of this, work like MIR instead
227226
Cast {
228227
kind: CastKind,
229228
value: VnIndex,
@@ -508,17 +507,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
508507
let val = self.ecx.binary_op(bin_op, &lhs, &rhs).ok()?;
509508
val.into()
510509
}
511-
CheckedBinaryOp(bin_op, lhs, rhs) => {
512-
let lhs = self.evaluated[lhs].as_ref()?;
513-
let lhs = self.ecx.read_immediate(lhs).ok()?;
514-
let rhs = self.evaluated[rhs].as_ref()?;
515-
let rhs = self.ecx.read_immediate(rhs).ok()?;
516-
let val = self
517-
.ecx
518-
.binary_op(bin_op.wrapping_to_overflowing().unwrap(), &lhs, &rhs)
519-
.ok()?;
520-
val.into()
521-
}
522510
Cast { kind, value, from: _, to } => match kind {
523511
CastKind::IntToInt | CastKind::IntToFloat => {
524512
let value = self.evaluated[value].as_ref()?;
@@ -829,17 +817,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
829817
let lhs = lhs?;
830818
let rhs = rhs?;
831819

832-
if let Some(op) = op.overflowing_to_wrapping() {
833-
if let Some(value) = self.simplify_binary(op, true, ty, lhs, rhs) {
834-
return Some(value);
835-
}
836-
Value::CheckedBinaryOp(op, lhs, rhs)
837-
} else {
838-
if let Some(value) = self.simplify_binary(op, false, ty, lhs, rhs) {
839-
return Some(value);
840-
}
841-
Value::BinaryOp(op, lhs, rhs)
820+
if let Some(value) = self.simplify_binary(op, ty, lhs, rhs) {
821+
return Some(value);
842822
}
823+
Value::BinaryOp(op, lhs, rhs)
843824
}
844825
Rvalue::UnaryOp(op, ref mut arg) => {
845826
let arg = self.simplify_operand(arg, location)?;
@@ -970,7 +951,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
970951
fn simplify_binary(
971952
&mut self,
972953
op: BinOp,
973-
checked: bool,
974954
lhs_ty: Ty<'tcx>,
975955
lhs: VnIndex,
976956
rhs: VnIndex,
@@ -999,22 +979,39 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
999979
use Either::{Left, Right};
1000980
let a = as_bits(lhs).map_or(Right(lhs), Left);
1001981
let b = as_bits(rhs).map_or(Right(rhs), Left);
982+
1002983
let result = match (op, a, b) {
1003984
// Neutral elements.
1004-
(BinOp::Add | BinOp::BitOr | BinOp::BitXor, Left(0), Right(p))
985+
(
986+
BinOp::Add
987+
| BinOp::AddWithOverflow
988+
| BinOp::AddUnchecked
989+
| BinOp::BitOr
990+
| BinOp::BitXor,
991+
Left(0),
992+
Right(p),
993+
)
1005994
| (
1006995
BinOp::Add
996+
| BinOp::AddWithOverflow
997+
| BinOp::AddUnchecked
1007998
| BinOp::BitOr
1008999
| BinOp::BitXor
10091000
| BinOp::Sub
1001+
| BinOp::SubWithOverflow
1002+
| BinOp::SubUnchecked
10101003
| BinOp::Offset
10111004
| BinOp::Shl
10121005
| BinOp::Shr,
10131006
Right(p),
10141007
Left(0),
10151008
)
1016-
| (BinOp::Mul, Left(1), Right(p))
1017-
| (BinOp::Mul | BinOp::Div, Right(p), Left(1)) => p,
1009+
| (BinOp::Mul | BinOp::MulWithOverflow | BinOp::MulUnchecked, Left(1), Right(p))
1010+
| (
1011+
BinOp::Mul | BinOp::MulWithOverflow | BinOp::MulUnchecked | BinOp::Div,
1012+
Right(p),
1013+
Left(1),
1014+
) => p,
10181015
// Attempt to simplify `x & ALL_ONES` to `x`, with `ALL_ONES` depending on type size.
10191016
(BinOp::BitAnd, Right(p), Left(ones)) | (BinOp::BitAnd, Left(ones), Right(p))
10201017
if ones == layout.size.truncate(u128::MAX)
@@ -1023,10 +1020,21 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
10231020
p
10241021
}
10251022
// Absorbing elements.
1026-
(BinOp::Mul | BinOp::BitAnd, _, Left(0))
1023+
(
1024+
BinOp::Mul | BinOp::MulWithOverflow | BinOp::MulUnchecked | BinOp::BitAnd,
1025+
_,
1026+
Left(0),
1027+
)
10271028
| (BinOp::Rem, _, Left(1))
10281029
| (
1029-
BinOp::Mul | BinOp::Div | BinOp::Rem | BinOp::BitAnd | BinOp::Shl | BinOp::Shr,
1030+
BinOp::Mul
1031+
| BinOp::MulWithOverflow
1032+
| BinOp::MulUnchecked
1033+
| BinOp::Div
1034+
| BinOp::Rem
1035+
| BinOp::BitAnd
1036+
| BinOp::Shl
1037+
| BinOp::Shr,
10301038
Left(0),
10311039
_,
10321040
) => self.insert_scalar(Scalar::from_uint(0u128, layout.size), lhs_ty),
@@ -1038,7 +1046,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
10381046
self.insert_scalar(Scalar::from_uint(ones, layout.size), lhs_ty)
10391047
}
10401048
// Sub/Xor with itself.
1041-
(BinOp::Sub | BinOp::BitXor, a, b) if a == b => {
1049+
(BinOp::Sub | BinOp::SubWithOverflow | BinOp::SubUnchecked | BinOp::BitXor, a, b)
1050+
if a == b =>
1051+
{
10421052
self.insert_scalar(Scalar::from_uint(0u128, layout.size), lhs_ty)
10431053
}
10441054
// Comparison:
@@ -1052,7 +1062,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
10521062
_ => return None,
10531063
};
10541064

1055-
if checked {
1065+
if op.is_overflowing() {
10561066
let false_val = self.insert_bool(false);
10571067
Some(self.insert_tuple(vec![result, false_val]))
10581068
} else {

‎compiler/rustc_resolve/src/ident.rs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -965,6 +965,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
965965
// if it can then our result is not determined and can be invalidated.
966966
for single_import in &resolution.single_imports {
967967
let Some(import_vis) = single_import.vis.get() else {
968+
// This branch handles a cycle in single imports, which occurs
969+
// when we've previously captured the `vis` value during an import
970+
// process.
971+
//
972+
// For example:
973+
// ```
974+
// use a::b;
975+
// use b as a;
976+
// ```
977+
// 1. Steal the `vis` in `use a::b` and attempt to locate `a` in the
978+
// current module.
979+
// 2. Encounter the import `use b as a`, which is a `single_import` for `a`,
980+
// and try to find `b` in the current module.
981+
// 3. Re-encounter the `use a::b` import since it's a `single_import` of `b`.
982+
// This leads to entering this branch.
968983
continue;
969984
};
970985
if !self.is_accessible_from(import_vis, parent_scope.module) {
@@ -979,15 +994,25 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
979994
// named imports.
980995
continue;
981996
}
997+
982998
let Some(module) = single_import.imported_module.get() else {
983999
return Err((Undetermined, Weak::No));
9841000
};
985-
let ImportKind::Single { source: ident, .. } = single_import.kind else {
1001+
let ImportKind::Single { source: ident, source_bindings, .. } = &single_import.kind
1002+
else {
9861003
unreachable!();
9871004
};
1005+
if binding.map_or(false, |binding| binding.module().is_some())
1006+
&& source_bindings.iter().all(|binding| matches!(binding.get(), Err(Undetermined)))
1007+
{
1008+
// This branch allows the binding to be defined or updated later,
1009+
// avoiding module inconsistency between the resolve process and the finalize process.
1010+
// See more details in #124840
1011+
return Err((Undetermined, Weak::No));
1012+
}
9881013
match self.resolve_ident_in_module(
9891014
module,
990-
ident,
1015+
*ident,
9911016
ns,
9921017
&single_import.parent_scope,
9931018
None,

‎compiler/rustc_resolve/src/imports.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,9 +352,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
352352
(old_glob @ true, false) | (old_glob @ false, true) => {
353353
let (glob_binding, nonglob_binding) =
354354
if old_glob { (old_binding, binding) } else { (binding, old_binding) };
355-
if glob_binding.res() != nonglob_binding.res()
356-
&& key.ns == MacroNS
355+
if key.ns == MacroNS
357356
&& nonglob_binding.expansion != LocalExpnId::ROOT
357+
&& glob_binding.res() != nonglob_binding.res()
358358
{
359359
resolution.binding = Some(this.ambiguity(
360360
AmbiguityKind::GlobVsExpanded,

‎compiler/rustc_trait_selection/src/traits/coherence.rs

Lines changed: 24 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -924,11 +924,12 @@ where
924924
}
925925
}
926926

927-
ty::Alias(kind @ (ty::Projection | ty::Inherent | ty::Weak), ..) => {
928-
if ty.has_type_flags(ty::TypeFlags::HAS_TY_PARAM) {
929-
bug!("unexpected ty param in alias ty");
930-
}
931-
927+
// A rigid alias may normalize to anything.
928+
// * If it references an infer var, placeholder or bound ty, it may
929+
// normalize to that, so we have to treat it as an uncovered ty param.
930+
// * Otherwise it may normalize to any non-type-generic type
931+
// be it local or non-local.
932+
ty::Alias(kind, _) => {
932933
if ty.has_type_flags(
933934
ty::TypeFlags::HAS_TY_PLACEHOLDER
934935
| ty::TypeFlags::HAS_TY_BOUND
@@ -948,7 +949,24 @@ where
948949
}
949950
}
950951
} else {
951-
ControlFlow::Continue(())
952+
// Regarding *opaque types* specifically, we choose to treat them as non-local,
953+
// even those that appear within the same crate. This seems somewhat surprising
954+
// at first, but makes sense when you consider that opaque types are supposed
955+
// to hide the underlying type *within the same crate*. When an opaque type is
956+
// used from outside the module where it is declared, it should be impossible to
957+
// observe anything about it other than the traits that it implements.
958+
//
959+
// The alternative would be to look at the underlying type to determine whether
960+
// or not the opaque type itself should be considered local.
961+
//
962+
// However, this could make it a breaking change to switch the underlying hidden
963+
// type from a local type to a remote type. This would violate the rule that
964+
// opaque types should be completely opaque apart from the traits that they
965+
// implement, so we don't use this behavior.
966+
// Addendum: Moreover, revealing the underlying type is likely to cause cycle
967+
// errors as we rely on coherence / the specialization graph during typeck.
968+
969+
self.found_non_local_ty(ty)
952970
}
953971
}
954972

@@ -990,35 +1008,6 @@ where
9901008
// auto trait impl applies. There will never be multiple impls, so we can just
9911009
// act as if it were a local type here.
9921010
ty::CoroutineWitness(..) => ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)),
993-
ty::Alias(ty::Opaque, ..) => {
994-
// This merits some explanation.
995-
// Normally, opaque types are not involved when performing
996-
// coherence checking, since it is illegal to directly
997-
// implement a trait on an opaque type. However, we might
998-
// end up looking at an opaque type during coherence checking
999-
// if an opaque type gets used within another type (e.g. as
1000-
// the type of a field) when checking for auto trait or `Sized`
1001-
// impls. This requires us to decide whether or not an opaque
1002-
// type should be considered 'local' or not.
1003-
//
1004-
// We choose to treat all opaque types as non-local, even
1005-
// those that appear within the same crate. This seems
1006-
// somewhat surprising at first, but makes sense when
1007-
// you consider that opaque types are supposed to hide
1008-
// the underlying type *within the same crate*. When an
1009-
// opaque type is used from outside the module
1010-
// where it is declared, it should be impossible to observe
1011-
// anything about it other than the traits that it implements.
1012-
//
1013-
// The alternative would be to look at the underlying type
1014-
// to determine whether or not the opaque type itself should
1015-
// be considered local. However, this could make it a breaking change
1016-
// to switch the underlying ('defining') type from a local type
1017-
// to a remote type. This would violate the rule that opaque
1018-
// types should be completely opaque apart from the traits
1019-
// that they implement, so we don't use this behavior.
1020-
self.found_non_local_ty(ty)
1021-
}
10221011
};
10231012
// A bit of a hack, the `OrphanChecker` is only used to visit a `TraitRef`, so
10241013
// the first type we visit is always the self type.

‎library/std/src/io/stdio.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,9 +1190,8 @@ pub trait IsTerminal: crate::sealed::Sealed {
11901190
///
11911191
/// - If you run this example by piping some text to it, e.g. `echo "foo" | path/to/executable`
11921192
/// it will print: `Hello foo`.
1193-
/// - If you instead run the example interactively by running the executable directly, it will
1194-
/// panic with the message "Expected input to be piped to the process".
1195-
///
1193+
/// - If you instead run the example interactively by running `path/to/executable` directly, it will
1194+
/// prompt for input.
11961195
///
11971196
/// [changes]: io#platform-specific-behavior
11981197
/// [`Stdin`]: crate::io::Stdin

‎library/std/src/sys/pal/sgx/thread.rs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub use self::task_queue::JoinNotifier;
1515

1616
mod task_queue {
1717
use super::wait_notify;
18-
use crate::sync::{Mutex, MutexGuard, Once};
18+
use crate::sync::{Mutex, MutexGuard};
1919

2020
pub type JoinHandle = wait_notify::Waiter;
2121

@@ -28,12 +28,12 @@ mod task_queue {
2828
}
2929

3030
pub(super) struct Task {
31-
p: Box<dyn FnOnce()>,
31+
p: Box<dyn FnOnce() + Send>,
3232
done: JoinNotifier,
3333
}
3434

3535
impl Task {
36-
pub(super) fn new(p: Box<dyn FnOnce()>) -> (Task, JoinHandle) {
36+
pub(super) fn new(p: Box<dyn FnOnce() + Send>) -> (Task, JoinHandle) {
3737
let (done, recv) = wait_notify::new();
3838
let done = JoinNotifier(Some(done));
3939
(Task { p, done }, recv)
@@ -45,18 +45,12 @@ mod task_queue {
4545
}
4646
}
4747

48-
#[cfg_attr(test, linkage = "available_externally")]
49-
#[export_name = "_ZN16__rust_internals3std3sys3sgx6thread15TASK_QUEUE_INITE"]
50-
static TASK_QUEUE_INIT: Once = Once::new();
5148
#[cfg_attr(test, linkage = "available_externally")]
5249
#[export_name = "_ZN16__rust_internals3std3sys3sgx6thread10TASK_QUEUEE"]
53-
static mut TASK_QUEUE: Option<Mutex<Vec<Task>>> = None;
50+
static TASK_QUEUE: Mutex<Vec<Task>> = Mutex::new(Vec::new());
5451

5552
pub(super) fn lock() -> MutexGuard<'static, Vec<Task>> {
56-
unsafe {
57-
TASK_QUEUE_INIT.call_once(|| TASK_QUEUE = Some(Default::default()));
58-
TASK_QUEUE.as_ref().unwrap().lock().unwrap()
59-
}
53+
TASK_QUEUE.lock().unwrap()
6054
}
6155
}
6256

@@ -101,7 +95,7 @@ pub mod wait_notify {
10195

10296
impl Thread {
10397
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
104-
pub unsafe fn new(_stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
98+
pub unsafe fn new(_stack: usize, p: Box<dyn FnOnce() + Send>) -> io::Result<Thread> {
10599
let mut queue_lock = task_queue::lock();
106100
unsafe { usercalls::launch_thread()? };
107101
let (task, handle) = task_queue::Task::new(p);

‎library/std/src/thread/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,8 @@ impl Builder {
561561
let main = Box::new(main);
562562
// SAFETY: dynamic size and alignment of the Box remain the same. See below for why the
563563
// lifetime change is justified.
564-
let main = unsafe { Box::from_raw(Box::into_raw(main) as *mut (dyn FnOnce() + 'static)) };
564+
let main =
565+
unsafe { Box::from_raw(Box::into_raw(main) as *mut (dyn FnOnce() + Send + 'static)) };
565566

566567
Ok(JoinInner {
567568
// SAFETY:
@@ -1544,7 +1545,7 @@ struct Packet<'scope, T> {
15441545
// The type `T` should already always be Send (otherwise the thread could not
15451546
// have been created) and the Packet is Sync because all access to the
15461547
// `UnsafeCell` synchronized (by the `join()` boundary), and `ScopeData` is Sync.
1547-
unsafe impl<'scope, T: Sync> Sync for Packet<'scope, T> {}
1548+
unsafe impl<'scope, T: Send> Sync for Packet<'scope, T> {}
15481549

15491550
impl<'scope, T> Drop for Packet<'scope, T> {
15501551
fn drop(&mut self) {

‎src/ci/docker/run.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,6 @@ else
270270
args="$args --volume $root_dir:/checkout$SRC_MOUNT_OPTION"
271271
args="$args --volume $objdir:/checkout/obj"
272272
args="$args --volume $HOME/.cargo:/cargo"
273-
args="$args --volume $HOME/rustsrc:$HOME/rustsrc"
274273
args="$args --volume /tmp/toolstate:/tmp/toolstate"
275274

276275
id=$(id -u)

‎src/ci/github-actions/jobs.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ envs:
6161

6262
try:
6363
<<: *production
64+
# The following env var activates faster `try` builds in `opt-dist` by, e.g.
65+
# - building only the more commonly useful components (we rarely need e.g. rust-docs in try
66+
# builds)
67+
# - not running `opt-dist`'s post-optimization smoke tests on the resulting toolchain
68+
#
69+
# If you *want* these to happen however, temporarily uncomment it before triggering a try build.
6470
DIST_TRY_BUILD: 1
6571

6672
auto:

‎src/tools/compiletest/src/header.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,6 +1268,8 @@ fn expand_variables(mut value: String, config: &Config) -> String {
12681268
const CWD: &str = "{{cwd}}";
12691269
const SRC_BASE: &str = "{{src-base}}";
12701270
const BUILD_BASE: &str = "{{build-base}}";
1271+
const SYSROOT_BASE: &str = "{{sysroot-base}}";
1272+
const TARGET_LINKER: &str = "{{target-linker}}";
12711273

12721274
if value.contains(CWD) {
12731275
let cwd = env::current_dir().unwrap();
@@ -1282,6 +1284,14 @@ fn expand_variables(mut value: String, config: &Config) -> String {
12821284
value = value.replace(BUILD_BASE, &config.build_base.to_string_lossy());
12831285
}
12841286

1287+
if value.contains(SYSROOT_BASE) {
1288+
value = value.replace(SYSROOT_BASE, &config.sysroot_base.to_string_lossy());
1289+
}
1290+
1291+
if value.contains(TARGET_LINKER) {
1292+
value = value.replace(TARGET_LINKER, config.target_linker.as_deref().unwrap_or(""));
1293+
}
1294+
12851295
value
12861296
}
12871297

‎src/tools/miri/tests/pass/function_calls/abi_compat.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,24 @@ fn main() {
8383
test_abi_compat(main as fn(), id::<i32> as fn(i32) -> i32);
8484
// - 1-ZST
8585
test_abi_compat((), [0u8; 0]);
86-
// - Guaranteed null-pointer-optimizations (RFC 3391).
86+
// - Guaranteed Option<X> null-pointer-optimizations (RFC 3391).
8787
test_abi_compat(&0u32 as *const u32, Some(&0u32));
8888
test_abi_compat(main as fn(), Some(main as fn()));
8989
test_abi_compat(0u32, Some(num::NonZero::new(1u32).unwrap()));
9090
test_abi_compat(&0u32 as *const u32, Some(Wrapper(&0u32)));
91-
test_abi_compat(0u32, Some(Wrapper(num::NonZero::new(1u32).unwrap())));
91+
test_abi_compat(0u32, Some(Wrapper(num::NonZeroU32::new(1u32).unwrap())));
92+
// - Guaranteed Result<X, ZST1> does the same as Option<X> (RFC 3391)
93+
test_abi_compat(&0u32 as *const u32, Result::<_, ()>::Ok(&0u32));
94+
test_abi_compat(main as fn(), Result::<_, ()>::Ok(main as fn()));
95+
test_abi_compat(0u32, Result::<_, ()>::Ok(num::NonZeroU32::new(1).unwrap()));
96+
test_abi_compat(&0u32 as *const u32, Result::<_, ()>::Ok(Wrapper(&0u32)));
97+
test_abi_compat(0u32, Result::<_, ()>::Ok(Wrapper(num::NonZeroU32::new(1).unwrap())));
98+
// - Guaranteed Result<ZST1, X> also does the same as Option<X> (RFC 3391)
99+
test_abi_compat(&0u32 as *const u32, Result::<(), _>::Err(&0u32));
100+
test_abi_compat(main as fn(), Result::<(), _>::Err(main as fn()));
101+
test_abi_compat(0u32, Result::<(), _>::Err(num::NonZeroU32::new(1).unwrap()));
102+
test_abi_compat(&0u32 as *const u32, Result::<(), _>::Err(Wrapper(&0u32)));
103+
test_abi_compat(0u32, Result::<(), _>::Err(Wrapper(num::NonZeroU32::new(1).unwrap())));
92104

93105
// These must work for *any* type, since we guarantee that `repr(transparent)` is ABI-compatible
94106
// with the wrapped field.

‎src/tools/tidy/src/issues.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2445,7 +2445,6 @@ ui/issues/issue-53300.rs
24452445
ui/issues/issue-53333.rs
24462446
ui/issues/issue-53348.rs
24472447
ui/issues/issue-53419.rs
2448-
ui/issues/issue-53498.rs
24492448
ui/issues/issue-53568.rs
24502449
ui/issues/issue-5358-1.rs
24512450
ui/issues/issue-53728.rs

‎src/tools/tidy/src/ui_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use std::path::{Path, PathBuf};
1515
const ENTRY_LIMIT: u32 = 900;
1616
// FIXME: The following limits should be reduced eventually.
1717

18-
const ISSUES_ENTRY_LIMIT: u32 = 1674;
18+
const ISSUES_ENTRY_LIMIT: u32 = 1672;
1919

2020
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
2121
"rs", // test source files

‎tests/crashes/124490.rs

Lines changed: 0 additions & 16 deletions
This file was deleted.

‎tests/crashes/125013-1.rs

Lines changed: 0 additions & 5 deletions
This file was deleted.

‎tests/crashes/125013-2.rs

Lines changed: 0 additions & 16 deletions
This file was deleted.

‎tests/run-make-fulldeps/issue-19371/Makefile

Lines changed: 0 additions & 9 deletions
This file was deleted.

‎tests/run-make-fulldeps/issue-19371/foo.rs renamed to ‎tests/ui-fulldeps/run-compiler-twice.rs

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,55 @@
1+
//@ edition: 2021
2+
//@ run-pass
3+
//@ run-flags: {{sysroot-base}} {{target-linker}}
4+
//@ ignore-stage1 (requires matching sysroot built with in-tree compiler)
5+
6+
// Regression test for <https://github.com/rust-lang/rust/issues/19371>.
7+
//
8+
// This test ensures that `compile_input` can be called twice in one task
9+
// without causing a panic.
10+
111
#![feature(rustc_private)]
212

313
extern crate rustc_driver;
414
extern crate rustc_interface;
515
extern crate rustc_session;
616
extern crate rustc_span;
717

18+
use std::path::{Path, PathBuf};
19+
820
use rustc_interface::interface;
921
use rustc_session::config::{Input, Options, OutFileName, OutputType, OutputTypes};
1022
use rustc_span::FileName;
1123

12-
use std::path::PathBuf;
13-
1424
fn main() {
1525
let src = r#"
1626
fn main() {}
1727
"#;
1828

1929
let args: Vec<String> = std::env::args().collect();
2030

21-
if args.len() < 4 {
22-
panic!("expected rustc path");
31+
if args.len() < 2 {
32+
panic!("expected sysroot (and optional linker)");
2333
}
2434

25-
let tmpdir = PathBuf::from(&args[1]);
26-
27-
let mut sysroot = PathBuf::from(&args[3]);
28-
sysroot.pop();
29-
sysroot.pop();
35+
let sysroot = PathBuf::from(&args[1]);
36+
let linker = args.get(2).map(PathBuf::from);
3037

31-
compile(src.to_string(), tmpdir.join("out"), sysroot.clone());
38+
// compiletest sets the current dir to `output_base_dir` when running.
39+
let tmpdir = std::env::current_dir().unwrap().join("tmp");
40+
std::fs::create_dir_all(&tmpdir).unwrap();
3241

33-
compile(src.to_string(), tmpdir.join("out"), sysroot.clone());
42+
compile(src.to_string(), tmpdir.join("out"), sysroot.clone(), linker.as_deref());
43+
compile(src.to_string(), tmpdir.join("out"), sysroot.clone(), linker.as_deref());
3444
}
3545

36-
fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
46+
fn compile(code: String, output: PathBuf, sysroot: PathBuf, linker: Option<&Path>) {
3747
let mut opts = Options::default();
3848
opts.output_types = OutputTypes::new(&[(OutputType::Exe, None)]);
3949
opts.maybe_sysroot = Some(sysroot);
4050

41-
if let Ok(linker) = std::env::var("RUSTC_LINKER") {
42-
opts.cg.linker = Some(linker.into());
51+
if let Some(linker) = linker {
52+
opts.cg.linker = Some(linker.to_owned());
4353
}
4454

4555
let name = FileName::anon_source_code(&code);
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
2+
--> $DIR/orphan-check-opaque-types-not-covering.rs:17:6
3+
|
4+
LL | impl<T> foreign::Trait0<Local, T, ()> for Identity<T> {}
5+
| ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
6+
|
7+
= note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
8+
= note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
9+
10+
error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
11+
--> $DIR/orphan-check-opaque-types-not-covering.rs:26:6
12+
|
13+
LL | impl<T> foreign::Trait1<Local, T> for Opaque<T> {}
14+
| ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
15+
|
16+
= note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
17+
= note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
18+
19+
error: aborting due to 2 previous errors
20+
21+
For more information about this error, try `rustc --explain E0210`.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
2+
--> $DIR/orphan-check-opaque-types-not-covering.rs:17:6
3+
|
4+
LL | impl<T> foreign::Trait0<Local, T, ()> for Identity<T> {}
5+
| ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
6+
|
7+
= note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
8+
= note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
9+
10+
error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
11+
--> $DIR/orphan-check-opaque-types-not-covering.rs:26:6
12+
|
13+
LL | impl<T> foreign::Trait1<Local, T> for Opaque<T> {}
14+
| ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
15+
|
16+
= note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
17+
= note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
18+
19+
error: aborting due to 2 previous errors
20+
21+
For more information about this error, try `rustc --explain E0210`.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Opaque types never cover type parameters.
2+
3+
//@ revisions: classic next
4+
//@[next] compile-flags: -Znext-solver
5+
6+
//@ aux-crate:foreign=parametrized-trait.rs
7+
//@ edition:2021
8+
9+
#![feature(type_alias_impl_trait)]
10+
11+
type Identity<T> = impl Sized;
12+
13+
fn define_identity<T>(x: T) -> Identity<T> {
14+
x
15+
}
16+
17+
impl<T> foreign::Trait0<Local, T, ()> for Identity<T> {}
18+
//~^ ERROR type parameter `T` must be covered by another type
19+
20+
type Opaque<T> = impl Sized;
21+
22+
fn define_local<T>() -> Opaque<T> {
23+
Local
24+
}
25+
26+
impl<T> foreign::Trait1<Local, T> for Opaque<T> {}
27+
//~^ ERROR type parameter `T` must be covered by another type
28+
29+
struct Local;
30+
31+
fn main() {}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//@ check-pass
2+
3+
// https://github.com/rust-lang/rust/pull/124840#issuecomment-2098148587
4+
5+
mod a {
6+
pub(crate) use crate::S;
7+
}
8+
mod b {
9+
pub struct S;
10+
}
11+
use self::a::S;
12+
use self::b::*;
13+
14+
fn main() {}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//@ check-pass
2+
3+
// similar `cycle-import-in-diff-module-0.rs`
4+
5+
mod a {
6+
pub(crate) use crate::s;
7+
}
8+
mod b {
9+
pub mod s {}
10+
}
11+
use self::b::*;
12+
use self::a::s;
13+
14+
fn main() {}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// https://github.com/rust-lang/rust/issues/124490
2+
3+
mod a {
4+
pub mod b {
5+
pub mod c {}
6+
}
7+
}
8+
9+
use a::*;
10+
11+
use b::c;
12+
//~^ ERROR: cannot determine resolution for the import
13+
//~| ERROR: cannot determine resolution for the import
14+
//~| ERROR: unresolved import `b::c`
15+
use c as b;
16+
17+
fn main() {}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
error: cannot determine resolution for the import
2+
--> $DIR/shadow-glob-module-resolution-1.rs:11:5
3+
|
4+
LL | use b::c;
5+
| ^^^^
6+
7+
error: cannot determine resolution for the import
8+
--> $DIR/shadow-glob-module-resolution-1.rs:11:5
9+
|
10+
LL | use b::c;
11+
| ^^^^
12+
|
13+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
14+
15+
error[E0432]: unresolved import `b::c`
16+
--> $DIR/shadow-glob-module-resolution-1.rs:11:5
17+
|
18+
LL | use b::c;
19+
| ^^^^
20+
21+
error: aborting due to 3 previous errors
22+
23+
For more information about this error, try `rustc --explain E0432`.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// https://github.com/rust-lang/rust/issues/125013
2+
3+
mod a {
4+
pub mod b {
5+
pub mod c {
6+
pub trait D {}
7+
}
8+
}
9+
}
10+
11+
use a::*;
12+
13+
use e as b;
14+
//~^ ERROR: unresolved import `e`
15+
use b::c::D as e;
16+
//~^ ERROR: cannot determine resolution for the import
17+
//~| ERROR: cannot determine resolution for the import
18+
19+
fn main() { }
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
error: cannot determine resolution for the import
2+
--> $DIR/shadow-glob-module-resolution-2.rs:15:5
3+
|
4+
LL | use b::c::D as e;
5+
| ^^^^^^^^^^^^
6+
7+
error: cannot determine resolution for the import
8+
--> $DIR/shadow-glob-module-resolution-2.rs:15:5
9+
|
10+
LL | use b::c::D as e;
11+
| ^^^^^^^^^^^^
12+
|
13+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
14+
15+
error[E0432]: unresolved import `e`
16+
--> $DIR/shadow-glob-module-resolution-2.rs:13:5
17+
|
18+
LL | use e as b;
19+
| -^^^^^
20+
| |
21+
| no `e` in the root
22+
| help: a similar name exists in the module: `a`
23+
24+
error: aborting due to 3 previous errors
25+
26+
For more information about this error, try `rustc --explain E0432`.

‎tests/ui/issues/issue-53498.rs

Lines changed: 0 additions & 17 deletions
This file was deleted.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0599]: no function or associated item named `foo` found for struct `Foo<B>` in the current scope
2+
--> $DIR/ufc-method-call.rs:27:27
3+
|
4+
LL | pub struct Foo<T>(T);
5+
| ----------------- function or associated item `foo` not found for this struct
6+
...
7+
LL | test::Foo::<test::B>::foo();
8+
| ^^^ function or associated item not found in `Foo<B>`
9+
|
10+
= note: the function or associated item was found for
11+
- `Foo<A>`
12+
13+
error: aborting due to 1 previous error
14+
15+
For more information about this error, try `rustc --explain E0599`.

‎tests/ui/privacy/ufc-method-call.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//! This test used to report that the method call cannot
2+
//! call the private method `Foo<A>::foo`, even though the user
3+
//! explicitly selected `Foo<B>::foo`. This is because we only
4+
//! looked for methods of the right name, without properly checking
5+
//! the `Self` type
6+
7+
//@ revisions: same_name different_name
8+
9+
pub mod test {
10+
pub struct A;
11+
pub struct B;
12+
pub struct Foo<T>(T);
13+
14+
impl Foo<A> {
15+
fn foo() {}
16+
}
17+
18+
impl Foo<B> {
19+
#[cfg(same_name)]
20+
fn foo() {}
21+
#[cfg(different_name)]
22+
fn bar() {}
23+
}
24+
}
25+
26+
fn main() {
27+
test::Foo::<test::B>::foo();
28+
//[same_name]~^ ERROR associated function `foo` is private
29+
//[different_name]~^^ ERROR no function or associated item named `foo` found for struct `Foo<B>`
30+
}

‎tests/ui/issues/issue-53498.stderr renamed to ‎tests/ui/privacy/ufc-method-call.same_name.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0624]: associated function `foo` is private
2-
--> $DIR/issue-53498.rs:16:27
2+
--> $DIR/ufc-method-call.rs:27:27
33
|
44
LL | fn foo() {}
55
| -------- private associated function defined here

‎tests/ui/type-alias-impl-trait/coherence.stderr renamed to ‎tests/ui/type-alias-impl-trait/coherence.classic.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
2-
--> $DIR/coherence.rs:14:1
2+
--> $DIR/coherence.rs:16:1
33
|
44
LL | impl foreign_crate::ForeignTrait for AliasOfForeignType<()> {}
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
2+
--> $DIR/coherence.rs:16:1
3+
|
4+
LL | impl foreign_crate::ForeignTrait for AliasOfForeignType<()> {}
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------
6+
| | |
7+
| | `AliasOfForeignType<()>` is not defined in the current crate
8+
| impl doesn't use only types from inside the current crate
9+
|
10+
= note: define and implement a trait or new type instead
11+
12+
error: aborting due to 1 previous error
13+
14+
For more information about this error, try `rustc --explain E0117`.

‎tests/ui/type-alias-impl-trait/coherence.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
//@ aux-build:foreign-crate.rs
2+
//@ revisions: classic next
3+
//@[next] compile-flags: -Znext-solver
24
#![feature(type_alias_impl_trait)]
35

46
extern crate foreign_crate;

0 commit comments

Comments
 (0)
This repository has been archived.