Skip to content

Rollup of 5 pull requests #99133

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jul 11, 2022
38 changes: 33 additions & 5 deletions compiler/rustc_borrowck/src/region_infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// The idea then is to lower the `T: 'X` constraint into multiple
/// bounds -- e.g., if `'X` is the union of two free lifetimes,
/// `'1` and `'2`, then we would create `T: '1` and `T: '2`.
#[instrument(level = "debug", skip(self, infcx, propagated_outlives_requirements))]
fn try_promote_type_test(
&self,
infcx: &InferCtxt<'_, 'tcx>,
Expand All @@ -934,11 +935,41 @@ impl<'tcx> RegionInferenceContext<'tcx> {
return false;
};

debug!("subject = {:?}", subject);

let r_scc = self.constraint_sccs.scc(*lower_bound);

debug!(
"lower_bound = {:?} r_scc={:?} universe={:?}",
lower_bound, r_scc, self.scc_universes[r_scc]
);

// If the type test requires that `T: 'a` where `'a` is a
// placeholder from another universe, that effectively requires
// `T: 'static`, so we have to propagate that requirement.
//
// It doesn't matter *what* universe because the promoted `T` will
// always be in the root universe.
if let Some(p) = self.scc_values.placeholders_contained_in(r_scc).next() {
debug!("encountered placeholder in higher universe: {:?}, requiring 'static", p);
let static_r = self.universal_regions.fr_static;
propagated_outlives_requirements.push(ClosureOutlivesRequirement {
subject,
outlived_free_region: static_r,
blame_span: locations.span(body),
category: ConstraintCategory::Boring,
});

// we can return here -- the code below might push add'l constraints
// but they would all be weaker than this one.
return true;
}

// For each region outlived by lower_bound find a non-local,
// universal region (it may be the same region) and add it to
// `ClosureOutlivesRequirement`.
let r_scc = self.constraint_sccs.scc(*lower_bound);
for ur in self.scc_values.universal_regions_outlived_by(r_scc) {
debug!("universal_region_outlived_by ur={:?}", ur);
// Check whether we can already prove that the "subject" outlives `ur`.
// If so, we don't have to propagate this requirement to our caller.
//
Expand All @@ -963,8 +994,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
continue;
}

debug!("try_promote_type_test: ur={:?}", ur);

let non_local_ub = self.universal_region_relations.non_local_upper_bounds(ur);
debug!("try_promote_type_test: non_local_ub={:?}", non_local_ub);

Expand Down Expand Up @@ -1001,15 +1030,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// will use it's *external name*, which will be a `RegionKind`
/// variant that can be used in query responses such as
/// `ReEarlyBound`.
#[instrument(level = "debug", skip(self, infcx))]
fn try_promote_type_test_subject(
&self,
infcx: &InferCtxt<'_, 'tcx>,
ty: Ty<'tcx>,
) -> Option<ClosureOutlivesSubject<'tcx>> {
let tcx = infcx.tcx;

debug!("try_promote_type_test_subject(ty = {:?})", ty);

let ty = tcx.fold_regions(ty, |r, _depth| {
let region_vid = self.to_region_vid(r);

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_trait_selection/src/traits/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::traits::{
self, FulfillmentContext, Normalized, Obligation, ObligationCause, PredicateObligation,
PredicateObligations, SelectionContext,
};
//use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::Diagnostic;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
Expand Down Expand Up @@ -44,7 +44,7 @@ pub enum Conflict {

pub struct OverlapResult<'tcx> {
pub impl_header: ty::ImplHeader<'tcx>,
pub intercrate_ambiguity_causes: Vec<IntercrateAmbiguityCause>,
pub intercrate_ambiguity_causes: FxIndexSet<IntercrateAmbiguityCause>,

/// `true` if the overlap might've been permitted before the shift
/// to universes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc }
};
debug!(?cause, "evaluate_stack: pushing cause");
self.intercrate_ambiguity_causes.as_mut().unwrap().push(cause);
self.intercrate_ambiguity_causes.as_mut().unwrap().insert(cause);
}
}
}
Expand Down
14 changes: 7 additions & 7 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::traits::error_reporting::InferCtxtExt;
use crate::traits::project::ProjectAndUnifyResult;
use crate::traits::project::ProjectionCacheKeyExt;
use crate::traits::ProjectionCacheKey;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::{Diagnostic, ErrorGuaranteed};
use rustc_hir as hir;
Expand Down Expand Up @@ -52,7 +52,7 @@ pub use rustc_middle::traits::select::*;
mod candidate_assembly;
mod confirmation;

#[derive(Clone, Debug)]
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub enum IntercrateAmbiguityCause {
DownstreamCrate { trait_desc: String, self_desc: Option<String> },
UpstreamCrateUpdate { trait_desc: String, self_desc: Option<String> },
Expand Down Expand Up @@ -128,7 +128,7 @@ pub struct SelectionContext<'cx, 'tcx> {
/// We don't do his until we detect a coherence error because it can
/// lead to false overflow results (#47139) and because always
/// computing it may negatively impact performance.
intercrate_ambiguity_causes: Option<Vec<IntercrateAmbiguityCause>>,
intercrate_ambiguity_causes: Option<FxIndexSet<IntercrateAmbiguityCause>>,

/// The mode that trait queries run in, which informs our error handling
/// policy. In essence, canonicalized queries need their errors propagated
Expand Down Expand Up @@ -254,14 +254,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
pub fn enable_tracking_intercrate_ambiguity_causes(&mut self) {
assert!(self.intercrate);
assert!(self.intercrate_ambiguity_causes.is_none());
self.intercrate_ambiguity_causes = Some(vec![]);
self.intercrate_ambiguity_causes = Some(FxIndexSet::default());
debug!("selcx: enable_tracking_intercrate_ambiguity_causes");
}

/// Gets the intercrate ambiguity causes collected since tracking
/// was enabled and disables tracking at the same time. If
/// tracking is not enabled, just returns an empty vector.
pub fn take_intercrate_ambiguity_causes(&mut self) -> Vec<IntercrateAmbiguityCause> {
pub fn take_intercrate_ambiguity_causes(&mut self) -> FxIndexSet<IntercrateAmbiguityCause> {
assert!(self.intercrate);
self.intercrate_ambiguity_causes.take().unwrap_or_default()
}
Expand Down Expand Up @@ -960,7 +960,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
});

debug!(?cause, "evaluate_stack: pushing cause");
self.intercrate_ambiguity_causes.as_mut().unwrap().push(cause);
self.intercrate_ambiguity_causes.as_mut().unwrap().insert(cause);
}
}
}
Expand Down Expand Up @@ -1252,7 +1252,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
reservation impl ambiguity on {:?}",
def_id
);
intercrate_ambiguity_clauses.push(
intercrate_ambiguity_clauses.insert(
IntercrateAmbiguityCause::ReservationImpl {
message: value.to_string(),
},
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_trait_selection/src/traits/specialize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use specialization_graph::GraphExt;
use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt};
use crate::traits::select::IntercrateAmbiguityCause;
use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
use rustc_errors::{struct_span_err, EmissionGuarantee, LintDiagnosticBuilder};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
Expand All @@ -33,7 +33,7 @@ pub struct OverlapError {
pub with_impl: DefId,
pub trait_desc: String,
pub self_desc: Option<String>,
pub intercrate_ambiguity_causes: Vec<IntercrateAmbiguityCause>,
pub intercrate_ambiguity_causes: FxIndexSet<IntercrateAmbiguityCause>,
pub involves_placeholder: bool,
}

Expand Down
2 changes: 1 addition & 1 deletion library/core/src/sync/atomic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -991,7 +991,7 @@ impl<T> AtomicPtr<T> {
/// use std::sync::atomic::AtomicPtr;
///
/// let ptr = &mut 5;
/// let atomic_ptr = AtomicPtr::new(ptr);
/// let atomic_ptr = AtomicPtr::new(ptr);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down
4 changes: 2 additions & 2 deletions src/bootstrap/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,8 @@ pub(crate) fn maybe_download_ci_llvm(builder: &Builder<'_>) {
let key = format!("{}{}", llvm_sha, config.llvm_assertions);
if program_out_of_date(&llvm_stamp, &key) && !config.dry_run {
download_ci_llvm(builder, &llvm_sha);
for binary in ["llvm-config", "FileCheck"] {
builder.fix_bin_or_dylib(&llvm_root.join("bin").join(binary));
for entry in t!(fs::read_dir(llvm_root.join("bin"))) {
builder.fix_bin_or_dylib(&t!(entry).path());
}

// Update the timestamp of llvm-config to force rustc_llvm to be
Expand Down
4 changes: 1 addition & 3 deletions src/librustdoc/html/static/css/themes/dark.css
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,6 @@ a {
color: #D2991D;
}

a.test-arrow {
color: #dedede;
}
body.source .example-wrap pre.rust a {
background: #333;
}
Expand Down Expand Up @@ -255,6 +252,7 @@ pre.rust .question-mark {
}

a.test-arrow {
color: #dedede;
background-color: rgba(78, 139, 202, 0.2);
}

Expand Down
6 changes: 2 additions & 4 deletions src/librustdoc/html/static/css/themes/light.css
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,6 @@ a {
color: #3873AD;
}

a.test-arrow {
color: #f5f5f5;
}
body.source .example-wrap pre.rust a {
background: #eee;
}
Expand Down Expand Up @@ -239,7 +236,8 @@ pre.rust .question-mark {
}

a.test-arrow {
background-color: rgb(78, 139, 202, 0.2);
color: #f5f5f5;
background-color: rgba(78, 139, 202, 0.2);
}

a.test-arrow:hover{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ LL | impl<A:Iterator> Foo<A::Item> for A { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32`
|
= note: upstream crates may add a new impl of trait `std::iter::Iterator` for type `i32` in future versions
= note: upstream crates may add a new impl of trait `std::iter::Iterator` for type `i32` in future versions

error: aborting due to previous error

Expand Down
19 changes: 19 additions & 0 deletions src/test/ui/coherence/inter-crate-ambiguity-causes-notes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
struct S;

impl From<()> for S {
fn from(x: ()) -> Self {
S
}
}

impl<I> From<I> for S
//~^ ERROR conflicting implementations of trait
where
I: Iterator<Item = ()>,
{
fn from(x: I) -> Self {
S
}
}

fn main() {}
14 changes: 14 additions & 0 deletions src/test/ui/coherence/inter-crate-ambiguity-causes-notes.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error[E0119]: conflicting implementations of trait `std::convert::From<()>` for type `S`
--> $DIR/inter-crate-ambiguity-causes-notes.rs:9:1
|
LL | impl From<()> for S {
| ------------------- first implementation here
...
LL | impl<I> From<I> for S
| ^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `S`
|
= note: upstream crates may add a new impl of trait `std::iter::Iterator` for type `()` in future versions

error: aborting due to previous error

For more information about this error, try `rustc --explain E0119`.
1 change: 1 addition & 0 deletions src/test/ui/generic-associated-types/issue-91139.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ fn foo<T>() {
//~| ERROR `T` does not live long enough
//~| ERROR `T` does not live long enough
//~| ERROR `T` does not live long enough
//~| ERROR `T` may not live long enough
//
// FIXME: This error is bogus, but it arises because we try to validate
// that `<() as Foo<T>>::Type<'a>` is valid, which requires proving
Expand Down
14 changes: 13 additions & 1 deletion src/test/ui/generic-associated-types/issue-91139.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ error: `T` does not live long enough
LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
| ^^^^^^^^^

error[E0310]: the parameter type `T` may not live long enough
--> $DIR/issue-91139.rs:16:58
|
LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
| ^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
LL | fn foo<T: 'static>() {
| +++++++++

error: `T` does not live long enough
--> $DIR/issue-91139.rs:16:58
|
Expand All @@ -46,5 +57,6 @@ error: `T` does not live long enough
LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
| ^^^^^^^^^

error: aborting due to 8 previous errors
error: aborting due to 9 previous errors

For more information about this error, try `rustc --explain E0310`.
21 changes: 21 additions & 0 deletions src/test/ui/nll/issue-98693.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Regression test for #98693.
//
// The closure encounters an obligation that `T` must outlive `!U1`,
// a placeholder from universe U1. We were ignoring this placeholder
// when promoting the constraint to the enclosing function, and
// thus incorrectly judging the closure to be safe.

fn assert_static<T>()
where
for<'a> T: 'a,
{
}

fn test<T>() {
|| {
//~^ ERROR the parameter type `T` may not live long enough
assert_static::<T>();
};
}

fn main() {}
17 changes: 17 additions & 0 deletions src/test/ui/nll/issue-98693.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/issue-98693.rs:15:5
|
LL | / || {
LL | |
LL | | assert_static::<T>();
LL | | };
| |_____^ ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
LL | fn test<T: 'static>() {
| +++++++++

error: aborting due to previous error

For more information about this error, try `rustc --explain E0310`.