Skip to content
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

Rollup of 4 pull requests #71847

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/bootstrap/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ impl Step for Clippy {
host,
"test",
"src/tools/clippy",
SourceType::Submodule,
SourceType::InTree,
&[],
);

Expand Down
1 change: 0 additions & 1 deletion src/bootstrap/toolstate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ static STABLE_TOOLS: &[(&str, &str)] = &[
("edition-guide", "src/doc/edition-guide"),
("rls", "src/tools/rls"),
("rustfmt", "src/tools/rustfmt"),
("clippy-driver", "src/tools/clippy"),
];

// These tools are permitted to not build on the beta/stable channels.
Expand Down
25 changes: 25 additions & 0 deletions src/libcore/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1023,6 +1023,31 @@ impl<T: ?Sized> RefCell<T> {
}
}

impl<T: Default> RefCell<T> {
/// Takes the wrapped value, leaving `Default::default()` in its place.
///
/// # Panics
///
/// Panics if the value is currently borrowed.
///
/// # Examples
///
/// ```
/// #![feature(refcell_take)]
/// use std::cell::RefCell;
///
/// let c = RefCell::new(5);
/// let five = c.take();
///
/// assert_eq!(five, 5);
/// assert_eq!(c.into_inner(), 0);
/// ```
#[unstable(feature = "refcell_take", issue = "71395")]
pub fn take(&self) -> T {
self.replace(Default::default())
}
}

#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<T: ?Sized> Send for RefCell<T> where T: Send {}

Expand Down
72 changes: 45 additions & 27 deletions src/librustc_mir/borrow_check/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2290,36 +2290,54 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
right,
) => {
let ty_left = left.ty(body, tcx);
if let ty::RawPtr(_) | ty::FnPtr(_) = ty_left.kind {
let ty_right = right.ty(body, tcx);
let common_ty = self.infcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::MiscVariable,
span: body.source_info(location).span,
});
self.sub_types(
common_ty,
ty_left,
location.to_locations(),
ConstraintCategory::Boring,
)
.unwrap_or_else(|err| {
bug!("Could not equate type variable with {:?}: {:?}", ty_left, err)
});
if let Err(terr) = self.sub_types(
common_ty,
ty_right,
location.to_locations(),
ConstraintCategory::Boring,
) {
span_mirbug!(
self,
rvalue,
"unexpected comparison types {:?} and {:?} yields {:?}",
match ty_left.kind {
// Types with regions are comparable if they have a common super-type.
ty::RawPtr(_) | ty::FnPtr(_) => {
let ty_right = right.ty(body, tcx);
let common_ty = self.infcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::MiscVariable,
span: body.source_info(location).span,
});
self.relate_types(
common_ty,
ty::Variance::Contravariant,
ty_left,
ty_right,
terr
location.to_locations(),
ConstraintCategory::Boring,
)
.unwrap_or_else(|err| {
bug!("Could not equate type variable with {:?}: {:?}", ty_left, err)
});
if let Err(terr) = self.relate_types(
common_ty,
ty::Variance::Contravariant,
ty_right,
location.to_locations(),
ConstraintCategory::Boring,
) {
span_mirbug!(
self,
rvalue,
"unexpected comparison types {:?} and {:?} yields {:?}",
ty_left,
ty_right,
terr
)
}
}
// For types with no regions we can just check that the
// both operands have the same type.
ty::Int(_) | ty::Uint(_) | ty::Bool | ty::Char | ty::Float(_)
if ty_left == right.ty(body, tcx) => {}
// Other types are compared by trait methods, not by
// `Rvalue::BinaryOp`.
_ => span_mirbug!(
self,
rvalue,
"unexpected comparison types {:?} and {:?}",
ty_left,
right.ty(body, tcx)
),
}
}

Expand Down
18 changes: 15 additions & 3 deletions src/librustc_typeck/check/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode};
use smallvec::{smallvec, SmallVec};
use std::ops::Deref;

pub struct Coerce<'a, 'tcx> {
struct Coerce<'a, 'tcx> {
fcx: &'a FnCtxt<'a, 'tcx>,
cause: ObligationCause<'tcx>,
use_lub: bool,
Expand Down Expand Up @@ -126,15 +126,15 @@ fn success<'tcx>(
}

impl<'f, 'tcx> Coerce<'f, 'tcx> {
pub fn new(
fn new(
fcx: &'f FnCtxt<'f, 'tcx>,
cause: ObligationCause<'tcx>,
allow_two_phase: AllowTwoPhase,
) -> Self {
Coerce { fcx, cause, allow_two_phase, use_lub: false }
}

pub fn unify(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> InferResult<'tcx, Ty<'tcx>> {
fn unify(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> InferResult<'tcx, Ty<'tcx>> {
debug!("unify(a: {:?}, b: {:?}, use_lub: {})", a, b, self.use_lub);
self.commit_if_ok(|_| {
if self.use_lub {
Expand Down Expand Up @@ -841,6 +841,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.probe(|_| coerce.coerce(source, target)).is_ok()
}

/// Given a type and a target type, this function will calculate and return
/// how many dereference steps needed to achieve `expr_ty <: target`. If
/// it's not possible, return `None`.
pub fn deref_steps(&self, expr_ty: Ty<'tcx>, target: Ty<'tcx>) -> Option<usize> {
let cause = self.cause(rustc_span::DUMMY_SP, ObligationCauseCode::ExprAssignable);
// We don't ever need two-phase here since we throw out the result of the coercion
let coerce = Coerce::new(self, cause, AllowTwoPhase::No);
coerce
.autoderef(rustc_span::DUMMY_SP, expr_ty)
.find_map(|(ty, steps)| coerce.unify(ty, target).ok().map(|_| steps))
}

/// Given some expressions, their known unified type and another expression,
/// tries to unify the types, potentially inserting coercions on any of the
/// provided expressions and returns their LUB (aka "common supertype").
Expand Down
Loading