Auto merge of #102139 - Dylan-DPC:rollup-ljlipt8, r=Dylan-DPC
Rollup of 8 pull requests Successful merges: - #101598 (Update rustc's information on Android's sanitizers) - #102036 (Remove use of `io::ErrorKind::Other` in std) - #102037 (Make cycle errors recoverable) - #102069 (Skip `Equate` relation in `handle_opaque_type`) - #102076 (rustc_transmute: fix big-endian discriminants) - #102107 (Add missing space between notable trait tooltip and where clause) - #102119 (Fix a typo “pararmeter” in error message) - #102131 (Added which number is computed in compute_float.) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
89e4e1f1b3
26 changed files with 126 additions and 63 deletions
|
@ -1090,11 +1090,12 @@ fn add_sanitizer_libraries(sess: &Session, crate_type: CrateType, linker: &mut d
|
||||||
// both executables and dynamic shared objects. Everywhere else the runtimes
|
// both executables and dynamic shared objects. Everywhere else the runtimes
|
||||||
// are currently distributed as static libraries which should be linked to
|
// are currently distributed as static libraries which should be linked to
|
||||||
// executables only.
|
// executables only.
|
||||||
let needs_runtime = match crate_type {
|
let needs_runtime = !sess.target.is_like_android
|
||||||
CrateType::Executable => true,
|
&& match crate_type {
|
||||||
CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro => sess.target.is_like_osx,
|
CrateType::Executable => true,
|
||||||
CrateType::Rlib | CrateType::Staticlib => false,
|
CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro => sess.target.is_like_osx,
|
||||||
};
|
CrateType::Rlib | CrateType::Staticlib => false,
|
||||||
|
};
|
||||||
|
|
||||||
if !needs_runtime {
|
if !needs_runtime {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -95,6 +95,10 @@ pub trait ForestObligation: Clone + Debug {
|
||||||
pub trait ObligationProcessor {
|
pub trait ObligationProcessor {
|
||||||
type Obligation: ForestObligation;
|
type Obligation: ForestObligation;
|
||||||
type Error: Debug;
|
type Error: Debug;
|
||||||
|
type OUT: OutcomeTrait<
|
||||||
|
Obligation = Self::Obligation,
|
||||||
|
Error = Error<Self::Obligation, Self::Error>,
|
||||||
|
>;
|
||||||
|
|
||||||
fn needs_process_obligation(&self, obligation: &Self::Obligation) -> bool;
|
fn needs_process_obligation(&self, obligation: &Self::Obligation) -> bool;
|
||||||
|
|
||||||
|
@ -111,7 +115,11 @@ pub trait ObligationProcessor {
|
||||||
/// In other words, if we had O1 which required O2 which required
|
/// In other words, if we had O1 which required O2 which required
|
||||||
/// O3 which required O1, we would give an iterator yielding O1,
|
/// O3 which required O1, we would give an iterator yielding O1,
|
||||||
/// O2, O3 (O1 is not yielded twice).
|
/// O2, O3 (O1 is not yielded twice).
|
||||||
fn process_backedge<'c, I>(&mut self, cycle: I, _marker: PhantomData<&'c Self::Obligation>)
|
fn process_backedge<'c, I>(
|
||||||
|
&mut self,
|
||||||
|
cycle: I,
|
||||||
|
_marker: PhantomData<&'c Self::Obligation>,
|
||||||
|
) -> Result<(), Self::Error>
|
||||||
where
|
where
|
||||||
I: Clone + Iterator<Item = &'c Self::Obligation>;
|
I: Clone + Iterator<Item = &'c Self::Obligation>;
|
||||||
}
|
}
|
||||||
|
@ -402,12 +410,11 @@ impl<O: ForestObligation> ObligationForest<O> {
|
||||||
|
|
||||||
/// Performs a fixpoint computation over the obligation list.
|
/// Performs a fixpoint computation over the obligation list.
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
pub fn process_obligations<P, OUT>(&mut self, processor: &mut P) -> OUT
|
pub fn process_obligations<P>(&mut self, processor: &mut P) -> P::OUT
|
||||||
where
|
where
|
||||||
P: ObligationProcessor<Obligation = O>,
|
P: ObligationProcessor<Obligation = O>,
|
||||||
OUT: OutcomeTrait<Obligation = O, Error = Error<O, P::Error>>,
|
|
||||||
{
|
{
|
||||||
let mut outcome = OUT::new();
|
let mut outcome = P::OUT::new();
|
||||||
|
|
||||||
// Fixpoint computation: we repeat until the inner loop stalls.
|
// Fixpoint computation: we repeat until the inner loop stalls.
|
||||||
loop {
|
loop {
|
||||||
|
@ -473,7 +480,7 @@ impl<O: ForestObligation> ObligationForest<O> {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.mark_successes();
|
self.mark_successes();
|
||||||
self.process_cycles(processor);
|
self.process_cycles(processor, &mut outcome);
|
||||||
self.compress(|obl| outcome.record_completed(obl));
|
self.compress(|obl| outcome.record_completed(obl));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -558,7 +565,7 @@ impl<O: ForestObligation> ObligationForest<O> {
|
||||||
|
|
||||||
/// Report cycles between all `Success` nodes, and convert all `Success`
|
/// Report cycles between all `Success` nodes, and convert all `Success`
|
||||||
/// nodes to `Done`. This must be called after `mark_successes`.
|
/// nodes to `Done`. This must be called after `mark_successes`.
|
||||||
fn process_cycles<P>(&mut self, processor: &mut P)
|
fn process_cycles<P>(&mut self, processor: &mut P, outcome: &mut P::OUT)
|
||||||
where
|
where
|
||||||
P: ObligationProcessor<Obligation = O>,
|
P: ObligationProcessor<Obligation = O>,
|
||||||
{
|
{
|
||||||
|
@ -568,7 +575,7 @@ impl<O: ForestObligation> ObligationForest<O> {
|
||||||
// to handle the no-op cases immediately to avoid the cost of the
|
// to handle the no-op cases immediately to avoid the cost of the
|
||||||
// function call.
|
// function call.
|
||||||
if node.state.get() == NodeState::Success {
|
if node.state.get() == NodeState::Success {
|
||||||
self.find_cycles_from_node(&mut stack, processor, index);
|
self.find_cycles_from_node(&mut stack, processor, index, outcome);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -576,8 +583,13 @@ impl<O: ForestObligation> ObligationForest<O> {
|
||||||
self.reused_node_vec = stack;
|
self.reused_node_vec = stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_cycles_from_node<P>(&self, stack: &mut Vec<usize>, processor: &mut P, index: usize)
|
fn find_cycles_from_node<P>(
|
||||||
where
|
&self,
|
||||||
|
stack: &mut Vec<usize>,
|
||||||
|
processor: &mut P,
|
||||||
|
index: usize,
|
||||||
|
outcome: &mut P::OUT,
|
||||||
|
) where
|
||||||
P: ObligationProcessor<Obligation = O>,
|
P: ObligationProcessor<Obligation = O>,
|
||||||
{
|
{
|
||||||
let node = &self.nodes[index];
|
let node = &self.nodes[index];
|
||||||
|
@ -586,17 +598,20 @@ impl<O: ForestObligation> ObligationForest<O> {
|
||||||
None => {
|
None => {
|
||||||
stack.push(index);
|
stack.push(index);
|
||||||
for &dep_index in node.dependents.iter() {
|
for &dep_index in node.dependents.iter() {
|
||||||
self.find_cycles_from_node(stack, processor, dep_index);
|
self.find_cycles_from_node(stack, processor, dep_index, outcome);
|
||||||
}
|
}
|
||||||
stack.pop();
|
stack.pop();
|
||||||
node.state.set(NodeState::Done);
|
node.state.set(NodeState::Done);
|
||||||
}
|
}
|
||||||
Some(rpos) => {
|
Some(rpos) => {
|
||||||
// Cycle detected.
|
// Cycle detected.
|
||||||
processor.process_backedge(
|
let result = processor.process_backedge(
|
||||||
stack[rpos..].iter().map(|&i| &self.nodes[i].obligation),
|
stack[rpos..].iter().map(|&i| &self.nodes[i].obligation),
|
||||||
PhantomData,
|
PhantomData,
|
||||||
);
|
);
|
||||||
|
if let Err(err) = result {
|
||||||
|
outcome.record_error(Error { error: err, backtrace: self.error_at(index) });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,7 @@ where
|
||||||
{
|
{
|
||||||
type Obligation = O;
|
type Obligation = O;
|
||||||
type Error = E;
|
type Error = E;
|
||||||
|
type OUT = TestOutcome<O, E>;
|
||||||
|
|
||||||
fn needs_process_obligation(&self, _obligation: &Self::Obligation) -> bool {
|
fn needs_process_obligation(&self, _obligation: &Self::Obligation) -> bool {
|
||||||
true
|
true
|
||||||
|
@ -76,10 +77,15 @@ where
|
||||||
(self.process_obligation)(obligation)
|
(self.process_obligation)(obligation)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_backedge<'c, I>(&mut self, _cycle: I, _marker: PhantomData<&'c Self::Obligation>)
|
fn process_backedge<'c, I>(
|
||||||
|
&mut self,
|
||||||
|
_cycle: I,
|
||||||
|
_marker: PhantomData<&'c Self::Obligation>,
|
||||||
|
) -> Result<(), Self::Error>
|
||||||
where
|
where
|
||||||
I: Clone + Iterator<Item = &'c Self::Obligation>,
|
I: Clone + Iterator<Item = &'c Self::Obligation>,
|
||||||
{
|
{
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_data_structures::vec_map::VecMap;
|
use rustc_data_structures::vec_map::VecMap;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_middle::traits::ObligationCause;
|
use rustc_middle::traits::ObligationCause;
|
||||||
|
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||||
use rustc_middle::ty::fold::BottomUpFolder;
|
use rustc_middle::ty::fold::BottomUpFolder;
|
||||||
use rustc_middle::ty::GenericArgKind;
|
use rustc_middle::ty::GenericArgKind;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
|
@ -176,16 +177,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
} else if let Some(res) = process(b, a) {
|
} else if let Some(res) = process(b, a) {
|
||||||
res
|
res
|
||||||
} else {
|
} else {
|
||||||
// Rerun equality check, but this time error out due to
|
let (a, b) = self.resolve_vars_if_possible((a, b));
|
||||||
// different types.
|
Err(TypeError::Sorts(ExpectedFound::new(true, a, b)))
|
||||||
match self.at(cause, param_env).define_opaque_types(false).eq(a, b) {
|
|
||||||
Ok(_) => span_bug!(
|
|
||||||
cause.span,
|
|
||||||
"opaque types are never equal to anything but themselves: {:#?}",
|
|
||||||
(a.kind(), b.kind())
|
|
||||||
),
|
|
||||||
Err(e) => Err(e),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,6 +113,8 @@ pub struct FulfillmentError<'tcx> {
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum FulfillmentErrorCode<'tcx> {
|
pub enum FulfillmentErrorCode<'tcx> {
|
||||||
|
/// Inherently impossible to fulfill; this trait is implemented if and only if it is already implemented.
|
||||||
|
CodeCycle(Vec<Obligation<'tcx, ty::Predicate<'tcx>>>),
|
||||||
CodeSelectionError(SelectionError<'tcx>),
|
CodeSelectionError(SelectionError<'tcx>),
|
||||||
CodeProjectionError(MismatchedProjectionTypes<'tcx>),
|
CodeProjectionError(MismatchedProjectionTypes<'tcx>),
|
||||||
CodeSubtypeError(ExpectedFound<Ty<'tcx>>, TypeError<'tcx>), // always comes from a SubtypePredicate
|
CodeSubtypeError(ExpectedFound<Ty<'tcx>>, TypeError<'tcx>), // always comes from a SubtypePredicate
|
||||||
|
|
|
@ -47,6 +47,7 @@ impl<'tcx> fmt::Debug for traits::FulfillmentErrorCode<'tcx> {
|
||||||
write!(f, "CodeConstEquateError({:?}, {:?})", a, b)
|
write!(f, "CodeConstEquateError({:?}, {:?})", a, b)
|
||||||
}
|
}
|
||||||
super::CodeAmbiguity => write!(f, "Ambiguity"),
|
super::CodeAmbiguity => write!(f, "Ambiguity"),
|
||||||
|
super::CodeCycle(ref cycle) => write!(f, "Cycle({:?})", cycle),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,7 +173,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
|
||||||
span,
|
span,
|
||||||
span_label: match res {
|
span_label: match res {
|
||||||
Res::Def(kind, def_id) if kind == DefKind::TyParam => {
|
Res::Def(kind, def_id) if kind == DefKind::TyParam => {
|
||||||
self.def_span(def_id).map(|span| (span, "found this type pararmeter"))
|
self.def_span(def_id).map(|span| (span, "found this type parameter"))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
use crate::spec::TargetOptions;
|
use crate::spec::{SanitizerSet, TargetOptions};
|
||||||
|
|
||||||
pub fn opts() -> TargetOptions {
|
pub fn opts() -> TargetOptions {
|
||||||
let mut base = super::linux_base::opts();
|
let mut base = super::linux_base::opts();
|
||||||
base.os = "android".into();
|
base.os = "android".into();
|
||||||
|
base.is_like_android = true;
|
||||||
base.default_dwarf_version = 2;
|
base.default_dwarf_version = 2;
|
||||||
base.has_thread_local = false;
|
base.has_thread_local = false;
|
||||||
|
base.supported_sanitizers = SanitizerSet::ADDRESS;
|
||||||
// This is for backward compatibility, see https://github.com/rust-lang/rust/issues/49867
|
// This is for backward compatibility, see https://github.com/rust-lang/rust/issues/49867
|
||||||
// for context. (At that time, there was no `-C force-unwind-tables`, so the only solution
|
// for context. (At that time, there was no `-C force-unwind-tables`, so the only solution
|
||||||
// was to always emit `uwtable`).
|
// was to always emit `uwtable`).
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
use crate::spec::{LinkerFlavor, StackProbeType, Target};
|
use crate::spec::{LinkerFlavor, SanitizerSet, StackProbeType, Target};
|
||||||
|
|
||||||
pub fn target() -> Target {
|
pub fn target() -> Target {
|
||||||
let mut base = super::linux_gnu_base::opts();
|
let mut base = super::linux_gnu_base::opts();
|
||||||
base.cpu = "pentium4".into();
|
base.cpu = "pentium4".into();
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
|
base.supported_sanitizers = SanitizerSet::ADDRESS;
|
||||||
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
|
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
|
||||||
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
base.stack_probes = StackProbeType::Call;
|
base.stack_probes = StackProbeType::Call;
|
||||||
|
|
|
@ -1381,6 +1381,8 @@ pub struct TargetOptions {
|
||||||
pub is_like_msvc: bool,
|
pub is_like_msvc: bool,
|
||||||
/// Whether a target toolchain is like WASM.
|
/// Whether a target toolchain is like WASM.
|
||||||
pub is_like_wasm: bool,
|
pub is_like_wasm: bool,
|
||||||
|
/// Whether a target toolchain is like Android, implying a Linux kernel and a Bionic libc
|
||||||
|
pub is_like_android: bool,
|
||||||
/// Default supported version of DWARF on this platform.
|
/// Default supported version of DWARF on this platform.
|
||||||
/// Useful because some platforms (osx, bsd) only want up to DWARF2.
|
/// Useful because some platforms (osx, bsd) only want up to DWARF2.
|
||||||
pub default_dwarf_version: u32,
|
pub default_dwarf_version: u32,
|
||||||
|
@ -1673,6 +1675,7 @@ impl Default for TargetOptions {
|
||||||
is_like_windows: false,
|
is_like_windows: false,
|
||||||
is_like_msvc: false,
|
is_like_msvc: false,
|
||||||
is_like_wasm: false,
|
is_like_wasm: false,
|
||||||
|
is_like_android: false,
|
||||||
default_dwarf_version: 4,
|
default_dwarf_version: 4,
|
||||||
allows_weak_linkage: true,
|
allows_weak_linkage: true,
|
||||||
has_rpath: false,
|
has_rpath: false,
|
||||||
|
@ -2320,6 +2323,7 @@ impl Target {
|
||||||
key!(is_like_windows, bool);
|
key!(is_like_windows, bool);
|
||||||
key!(is_like_msvc, bool);
|
key!(is_like_msvc, bool);
|
||||||
key!(is_like_wasm, bool);
|
key!(is_like_wasm, bool);
|
||||||
|
key!(is_like_android, bool);
|
||||||
key!(default_dwarf_version, u32);
|
key!(default_dwarf_version, u32);
|
||||||
key!(allows_weak_linkage, bool);
|
key!(allows_weak_linkage, bool);
|
||||||
key!(has_rpath, bool);
|
key!(has_rpath, bool);
|
||||||
|
@ -2570,6 +2574,7 @@ impl ToJson for Target {
|
||||||
target_option_val!(is_like_windows);
|
target_option_val!(is_like_windows);
|
||||||
target_option_val!(is_like_msvc);
|
target_option_val!(is_like_msvc);
|
||||||
target_option_val!(is_like_wasm);
|
target_option_val!(is_like_wasm);
|
||||||
|
target_option_val!(is_like_android);
|
||||||
target_option_val!(default_dwarf_version);
|
target_option_val!(default_dwarf_version);
|
||||||
target_option_val!(allows_weak_linkage);
|
target_option_val!(allows_weak_linkage);
|
||||||
target_option_val!(has_rpath);
|
target_option_val!(has_rpath);
|
||||||
|
|
|
@ -4,10 +4,12 @@
|
||||||
// general routines.
|
// general routines.
|
||||||
|
|
||||||
use crate::infer::{DefiningAnchor, TyCtxtInferExt};
|
use crate::infer::{DefiningAnchor, TyCtxtInferExt};
|
||||||
|
use crate::traits::error_reporting::InferCtxtExt;
|
||||||
use crate::traits::{
|
use crate::traits::{
|
||||||
ImplSource, Obligation, ObligationCause, SelectionContext, TraitEngine, TraitEngineExt,
|
ImplSource, Obligation, ObligationCause, SelectionContext, TraitEngine, TraitEngineExt,
|
||||||
Unimplemented,
|
Unimplemented,
|
||||||
};
|
};
|
||||||
|
use rustc_infer::traits::FulfillmentErrorCode;
|
||||||
use rustc_middle::traits::CodegenObligationError;
|
use rustc_middle::traits::CodegenObligationError;
|
||||||
use rustc_middle::ty::{self, TyCtxt};
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
|
|
||||||
|
@ -62,6 +64,14 @@ pub fn codegen_select_candidate<'tcx>(
|
||||||
// optimization to stop iterating early.
|
// optimization to stop iterating early.
|
||||||
let errors = fulfill_cx.select_all_or_error(&infcx);
|
let errors = fulfill_cx.select_all_or_error(&infcx);
|
||||||
if !errors.is_empty() {
|
if !errors.is_empty() {
|
||||||
|
// `rustc_monomorphize::collector` assumes there are no type errors.
|
||||||
|
// Cycle errors are the only post-monomorphization errors possible; emit them now so
|
||||||
|
// `rustc_ty_utils::resolve_associated_item` doesn't return `None` post-monomorphization.
|
||||||
|
for err in errors {
|
||||||
|
if let FulfillmentErrorCode::CodeCycle(cycle) = err.code {
|
||||||
|
infcx.report_overflow_error_cycle(&cycle);
|
||||||
|
}
|
||||||
|
}
|
||||||
return Err(CodegenObligationError::FulfillmentError);
|
return Err(CodegenObligationError::FulfillmentError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1540,6 +1540,9 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
diag.emit();
|
diag.emit();
|
||||||
}
|
}
|
||||||
|
FulfillmentErrorCode::CodeCycle(ref cycle) => {
|
||||||
|
self.report_overflow_error_cycle(cycle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,10 +25,9 @@ use super::Unimplemented;
|
||||||
use super::{FulfillmentError, FulfillmentErrorCode};
|
use super::{FulfillmentError, FulfillmentErrorCode};
|
||||||
use super::{ObligationCause, PredicateObligation};
|
use super::{ObligationCause, PredicateObligation};
|
||||||
|
|
||||||
use crate::traits::error_reporting::InferCtxtExt as _;
|
|
||||||
use crate::traits::project::PolyProjectionObligation;
|
use crate::traits::project::PolyProjectionObligation;
|
||||||
use crate::traits::project::ProjectionCacheKeyExt as _;
|
use crate::traits::project::ProjectionCacheKeyExt as _;
|
||||||
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
|
use crate::traits::query::evaluate_obligation::InferCtxtExt;
|
||||||
|
|
||||||
impl<'tcx> ForestObligation for PendingPredicateObligation<'tcx> {
|
impl<'tcx> ForestObligation for PendingPredicateObligation<'tcx> {
|
||||||
/// Note that we include both the `ParamEnv` and the `Predicate`,
|
/// Note that we include both the `ParamEnv` and the `Predicate`,
|
||||||
|
@ -224,6 +223,7 @@ fn mk_pending(os: Vec<PredicateObligation<'_>>) -> Vec<PendingPredicateObligatio
|
||||||
impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
|
impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
|
||||||
type Obligation = PendingPredicateObligation<'tcx>;
|
type Obligation = PendingPredicateObligation<'tcx>;
|
||||||
type Error = FulfillmentErrorCode<'tcx>;
|
type Error = FulfillmentErrorCode<'tcx>;
|
||||||
|
type OUT = Outcome<Self::Obligation, Self::Error>;
|
||||||
|
|
||||||
/// Identifies whether a predicate obligation needs processing.
|
/// Identifies whether a predicate obligation needs processing.
|
||||||
///
|
///
|
||||||
|
@ -594,14 +594,16 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
cycle: I,
|
cycle: I,
|
||||||
_marker: PhantomData<&'c PendingPredicateObligation<'tcx>>,
|
_marker: PhantomData<&'c PendingPredicateObligation<'tcx>>,
|
||||||
) where
|
) -> Result<(), FulfillmentErrorCode<'tcx>>
|
||||||
|
where
|
||||||
I: Clone + Iterator<Item = &'c PendingPredicateObligation<'tcx>>,
|
I: Clone + Iterator<Item = &'c PendingPredicateObligation<'tcx>>,
|
||||||
{
|
{
|
||||||
if self.selcx.coinductive_match(cycle.clone().map(|s| s.obligation.predicate)) {
|
if self.selcx.coinductive_match(cycle.clone().map(|s| s.obligation.predicate)) {
|
||||||
debug!("process_child_obligations: coinductive match");
|
debug!("process_child_obligations: coinductive match");
|
||||||
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
let cycle: Vec<_> = cycle.map(|c| c.obligation.clone()).collect();
|
let cycle: Vec<_> = cycle.map(|c| c.obligation.clone()).collect();
|
||||||
self.selcx.infcx().report_overflow_error_cycle(&cycle);
|
Err(FulfillmentErrorCode::CodeCycle(cycle))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -226,13 +226,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn intercrate(infcx: &'cx InferCtxt<'cx, 'tcx>) -> SelectionContext<'cx, 'tcx> {
|
pub fn intercrate(infcx: &'cx InferCtxt<'cx, 'tcx>) -> SelectionContext<'cx, 'tcx> {
|
||||||
SelectionContext {
|
SelectionContext { intercrate: true, ..SelectionContext::new(infcx) }
|
||||||
infcx,
|
|
||||||
freshener: infcx.freshener_keep_static(),
|
|
||||||
intercrate: true,
|
|
||||||
intercrate_ambiguity_causes: None,
|
|
||||||
query_mode: TraitQueryMode::Standard,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_query_mode(
|
pub fn with_query_mode(
|
||||||
|
@ -240,13 +234,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
query_mode: TraitQueryMode,
|
query_mode: TraitQueryMode,
|
||||||
) -> SelectionContext<'cx, 'tcx> {
|
) -> SelectionContext<'cx, 'tcx> {
|
||||||
debug!(?query_mode, "with_query_mode");
|
debug!(?query_mode, "with_query_mode");
|
||||||
SelectionContext {
|
SelectionContext { query_mode, ..SelectionContext::new(infcx) }
|
||||||
infcx,
|
|
||||||
freshener: infcx.freshener_keep_static(),
|
|
||||||
intercrate: false,
|
|
||||||
intercrate_ambiguity_causes: None,
|
|
||||||
query_mode,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enables tracking of intercrate ambiguity causes. See
|
/// Enables tracking of intercrate ambiguity causes. See
|
||||||
|
|
|
@ -404,7 +404,7 @@ pub(crate) mod rustc {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
trace!(?discr_layout, "computed discriminant layout");
|
trace!(?discr_layout, "computed discriminant layout");
|
||||||
variant_layout = variant_layout.extend(discr_layout).unwrap().0;
|
variant_layout = variant_layout.extend(discr_layout).unwrap().0;
|
||||||
tree = tree.then(Self::from_disr(discr, tcx, layout_summary.discriminant_size));
|
tree = tree.then(Self::from_discr(discr, tcx, layout_summary.discriminant_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next come fields.
|
// Next come fields.
|
||||||
|
@ -444,11 +444,21 @@ pub(crate) mod rustc {
|
||||||
Ok(tree)
|
Ok(tree)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_disr(discr: Discr<'tcx>, tcx: TyCtxt<'tcx>, size: usize) -> Self {
|
pub fn from_discr(discr: Discr<'tcx>, tcx: TyCtxt<'tcx>, size: usize) -> Self {
|
||||||
// FIXME(@jswrenn): I'm certain this is missing needed endian nuance.
|
use rustc_target::abi::Endian;
|
||||||
let bytes = discr.val.to_ne_bytes();
|
|
||||||
let bytes = &bytes[..size];
|
let bytes: [u8; 16];
|
||||||
Self::Seq(bytes.into_iter().copied().map(|b| Self::from_bits(b)).collect())
|
let bytes = match tcx.data_layout.endian {
|
||||||
|
Endian::Little => {
|
||||||
|
bytes = discr.val.to_le_bytes();
|
||||||
|
&bytes[..size]
|
||||||
|
}
|
||||||
|
Endian::Big => {
|
||||||
|
bytes = discr.val.to_be_bytes();
|
||||||
|
&bytes[bytes.len() - size..]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Self::Seq(bytes.iter().map(|&b| Self::from_bits(b)).collect())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ use crate::num::dec2flt::table::{
|
||||||
LARGEST_POWER_OF_FIVE, POWER_OF_FIVE_128, SMALLEST_POWER_OF_FIVE,
|
LARGEST_POWER_OF_FIVE, POWER_OF_FIVE_128, SMALLEST_POWER_OF_FIVE,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Compute a float using an extended-precision representation.
|
/// Compute w * 10^q using an extended-precision float representation.
|
||||||
///
|
///
|
||||||
/// Fast conversion of a the significant digits and decimal exponent
|
/// Fast conversion of a the significant digits and decimal exponent
|
||||||
/// a float to an extended representation with a binary float. This
|
/// a float to an extended representation with a binary float. This
|
||||||
|
|
|
@ -822,14 +822,14 @@ impl crate::os::linux::process::ChildExt for crate::process::Child {
|
||||||
self.handle
|
self.handle
|
||||||
.pidfd
|
.pidfd
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or_else(|| Error::new(ErrorKind::Other, "No pidfd was created."))
|
.ok_or_else(|| Error::new(ErrorKind::Uncategorized, "No pidfd was created."))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn take_pidfd(&mut self) -> io::Result<PidFd> {
|
fn take_pidfd(&mut self) -> io::Result<PidFd> {
|
||||||
self.handle
|
self.handle
|
||||||
.pidfd
|
.pidfd
|
||||||
.take()
|
.take()
|
||||||
.ok_or_else(|| Error::new(ErrorKind::Other, "No pidfd was created."))
|
.ok_or_else(|| Error::new(ErrorKind::Uncategorized, "No pidfd was created."))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -371,7 +371,7 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
|
||||||
format!("<br><span class=\"where\">where{where_preds}</span>")
|
format!("<br><span class=\"where\">where{where_preds}</span>")
|
||||||
} else {
|
} else {
|
||||||
let mut clause = br_with_padding;
|
let mut clause = br_with_padding;
|
||||||
clause.truncate(clause.len() - 5 * " ".len());
|
clause.truncate(clause.len() - 4 * " ".len());
|
||||||
write!(clause, "<span class=\"where\">where{where_preds}</span>")?;
|
write!(clause, "<span class=\"where\">where{where_preds}</span>")?;
|
||||||
clause
|
clause
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// check-pass
|
// check-pass
|
||||||
|
// compile-flags: -Znormalize-docs
|
||||||
// Regression test for <https://github.com/rust-lang/rust/issues/79459>.
|
// Regression test for <https://github.com/rust-lang/rust/issues/79459>.
|
||||||
pub trait Query {}
|
pub trait Query {}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
<div class="item-decl"><pre class="rust trait"><code>pub trait TraitWhere {
|
<div class="item-decl"><pre class="rust trait"><code>pub trait TraitWhere {
|
||||||
type <a href="#associatedtype.Item" class="associatedtype">Item</a><'a><br />   <span class="where">where<br />        Self: 'a</span>;
|
type <a href="#associatedtype.Item" class="associatedtype">Item</a><'a><br />    <span class="where">where<br />        Self: 'a</span>;
|
||||||
|
|
||||||
|
fn <a href="#method.func" class="fnname">func</a>(self)<br />    <span class="where">where<br />        Self: <a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a></span>,
|
||||||
|
{ ... }
|
||||||
|
<span class="item-spacer" /> fn <a href="#method.lines" class="fnname">lines</a>(self) -> <a class="struct" href="{{channel}}/std/io/struct.Lines.html" title="struct std::io::Lines">Lines</a><Self><br />    <span class="where">where<br />        Self: <a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a></span>,
|
||||||
|
{ ... }
|
||||||
}</code></pre></div>
|
}</code></pre></div>
|
|
@ -1,5 +1,7 @@
|
||||||
#![crate_name = "foo"]
|
#![crate_name = "foo"]
|
||||||
|
|
||||||
|
use std::io::Lines;
|
||||||
|
|
||||||
pub trait MyTrait { fn dummy(&self) { } }
|
pub trait MyTrait { fn dummy(&self) { } }
|
||||||
|
|
||||||
// @has foo/struct.Alpha.html '//pre' "pub struct Alpha<A>(_)where A: MyTrait"
|
// @has foo/struct.Alpha.html '//pre' "pub struct Alpha<A>(_)where A: MyTrait"
|
||||||
|
@ -29,6 +31,16 @@ where
|
||||||
// @snapshot SWhere_TraitWhere_item-decl - '//div[@class="item-decl"]'
|
// @snapshot SWhere_TraitWhere_item-decl - '//div[@class="item-decl"]'
|
||||||
pub trait TraitWhere {
|
pub trait TraitWhere {
|
||||||
type Item<'a> where Self: 'a;
|
type Item<'a> where Self: 'a;
|
||||||
|
|
||||||
|
fn func(self)
|
||||||
|
where
|
||||||
|
Self: Sized
|
||||||
|
{}
|
||||||
|
|
||||||
|
fn lines(self) -> Lines<Self>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{ todo!() }
|
||||||
}
|
}
|
||||||
|
|
||||||
// @has foo/struct.Echo.html '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
|
// @has foo/struct.Echo.html '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
|
||||||
|
|
|
@ -4,7 +4,7 @@ error[E0423]: expected value, found type parameter `T`
|
||||||
LL | impl<T> Bar<T> for [u8; T] {}
|
LL | impl<T> Bar<T> for [u8; T] {}
|
||||||
| - ^ not a value
|
| - ^ not a value
|
||||||
| |
|
| |
|
||||||
| found this type pararmeter
|
| found this type parameter
|
||||||
|
|
||||||
error[E0599]: the function or associated item `foo` exists for struct `Foo<_>`, but its trait bounds were not satisfied
|
error[E0599]: the function or associated item `foo` exists for struct `Foo<_>`, but its trait bounds were not satisfied
|
||||||
--> $DIR/issue-69654.rs:17:10
|
--> $DIR/issue-69654.rs:17:10
|
||||||
|
|
|
@ -2,7 +2,7 @@ error[E0574]: expected struct, variant or union type, found type parameter `T`
|
||||||
--> $DIR/lexical-scopes.rs:3:13
|
--> $DIR/lexical-scopes.rs:3:13
|
||||||
|
|
|
|
||||||
LL | fn f<T>() {
|
LL | fn f<T>() {
|
||||||
| - found this type pararmeter
|
| - found this type parameter
|
||||||
LL | let t = T { i: 0 };
|
LL | let t = T { i: 0 };
|
||||||
| ^ not a struct, variant or union type
|
| ^ not a struct, variant or union type
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ error[E0574]: expected struct, variant or union type, found type parameter `Baz`
|
||||||
--> $DIR/point-at-type-parameter-shadowing-another-type.rs:16:13
|
--> $DIR/point-at-type-parameter-shadowing-another-type.rs:16:13
|
||||||
|
|
|
|
||||||
LL | impl<Baz> Foo<Baz> for Bar {
|
LL | impl<Baz> Foo<Baz> for Bar {
|
||||||
| --- found this type pararmeter
|
| --- found this type parameter
|
||||||
...
|
...
|
||||||
LL | Baz { num } => num,
|
LL | Baz { num } => num,
|
||||||
| ^^^ not a struct, variant or union type
|
| ^^^ not a struct, variant or union type
|
||||||
|
|
|
@ -4,7 +4,7 @@ error[E0404]: expected trait, found type parameter `Add`
|
||||||
LL | impl<T: Clone, Add> Add for Foo<T> {
|
LL | impl<T: Clone, Add> Add for Foo<T> {
|
||||||
| --- ^^^ not a trait
|
| --- ^^^ not a trait
|
||||||
| |
|
| |
|
||||||
| found this type pararmeter
|
| found this type parameter
|
||||||
|
|
|
|
||||||
help: consider importing this trait instead
|
help: consider importing this trait instead
|
||||||
|
|
|
|
||||||
|
|
|
@ -11,9 +11,15 @@ mod tests;
|
||||||
pub const ASAN_SUPPORTED_TARGETS: &[&str] = &[
|
pub const ASAN_SUPPORTED_TARGETS: &[&str] = &[
|
||||||
"aarch64-apple-darwin",
|
"aarch64-apple-darwin",
|
||||||
"aarch64-fuchsia",
|
"aarch64-fuchsia",
|
||||||
|
"aarch64-linux-android",
|
||||||
"aarch64-unknown-linux-gnu",
|
"aarch64-unknown-linux-gnu",
|
||||||
|
"arm-linux-androideabi",
|
||||||
|
"armv7-linux-androideabi",
|
||||||
|
"i686-linux-android",
|
||||||
|
"i686-unknown-linux-gnu",
|
||||||
"x86_64-apple-darwin",
|
"x86_64-apple-darwin",
|
||||||
"x86_64-fuchsia",
|
"x86_64-fuchsia",
|
||||||
|
"x86_64-linux-android",
|
||||||
"x86_64-unknown-freebsd",
|
"x86_64-unknown-freebsd",
|
||||||
"x86_64-unknown-linux-gnu",
|
"x86_64-unknown-linux-gnu",
|
||||||
];
|
];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue