Skip to content

[WIP] Use Into::into in operator ? #60796

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

Closed
wants to merge 7 commits into from
Closed
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/libcore/ops/try.rs
Original file line number Diff line number Diff line change
@@ -34,7 +34,7 @@ pub trait Try {
///
/// If an `Err(e)` result is returned, the value `e` will be "wrapped"
/// in the return type of the enclosing scope (which must itself implement
/// `Try`). Specifically, the value `X::from_error(From::from(e))`
/// `Try`). Specifically, the value `X::from_error(Into::into(e))`
/// is returned, where `X` is the return type of the enclosing function.
#[unstable(feature = "try_trait", issue = "42327")]
fn into_result(self) -> Result<Self::Ok, Self::Error>;
2 changes: 1 addition & 1 deletion src/libcore/tests/result.rs
Original file line number Diff line number Diff line change
@@ -198,7 +198,7 @@ pub fn test_unwrap_or_default() {
#[test]
fn test_try() {
fn try_result_some() -> Option<u8> {
let val = Ok(1)?;
let val = Ok::<_, NoneError>(1)?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a huge ergonomic regression 😟

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I'm not too bothered by this as Ok(1)? instead of Some(1)? is a silly thing to do; I don't know why Ok(1)? works in the first place...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess inference can tell that the only possible From for NoneError is the blanket identity impl<T> From<T> for T, versus now inferring some T: Into<NoneError>.

Some(val)
}
assert_eq!(try_result_some(), Some(1));
2 changes: 1 addition & 1 deletion src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
@@ -370,7 +370,7 @@ impl fmt::Debug for DepNode {

write!(f, "(")?;

crate::ty::tls::with_opt(|opt_tcx| {
crate::ty::tls::with_opt(|opt_tcx| -> fmt::Result {
if let Some(tcx) = opt_tcx {
if let Some(def_id) = self.extract_def_id(tcx) {
write!(f, "{}", tcx.def_path_debug_str(def_id))?;
2 changes: 1 addition & 1 deletion src/librustc/hir/def_id.rs
Original file line number Diff line number Diff line change
@@ -171,7 +171,7 @@ impl fmt::Debug for DefId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "DefId({}:{}", self.krate, self.index.as_array_index())?;

ty::tls::with_opt(|opt_tcx| {
ty::tls::with_opt(|opt_tcx| -> fmt::Result {
if let Some(tcx) = opt_tcx {
write!(f, " ~ {}", tcx.def_path_debug_str(*self))?;
}
14 changes: 7 additions & 7 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
@@ -4755,9 +4755,9 @@ impl<'a> LoweringContext<'a> {
// Ok(val) => #[allow(unreachable_code)] val,
// Err(err) => #[allow(unreachable_code)]
// // If there is an enclosing `catch {...}`
// break 'catch_target Try::from_error(From::from(err)),
// break 'catch_target Try::from_error(Into::into(err)),
// // Otherwise
// return Try::from_error(From::from(err)),
// return Try::from_error(Into::into(err)),
// }

let unstable_span = self.sess.source_map().mark_span_with_reason(
@@ -4818,17 +4818,17 @@ impl<'a> LoweringContext<'a> {
};

// `Err(err) => #[allow(unreachable_code)]
// return Try::from_error(From::from(err)),`
// return Try::from_error(Into::into(err)),`
let err_arm = {
let err_ident = self.str_to_ident("err");
let (err_local, err_local_nid) = self.pat_ident(try_span, err_ident);
let from_expr = {
let from_path = &[sym::convert, sym::From, sym::from];
let into_expr = {
let into_path = &[sym::convert, sym::Into, sym::into];
let err_expr = self.expr_ident(try_span, err_ident, err_local_nid);
self.expr_call_std_path(try_span, from_path, hir_vec![err_expr])
self.expr_call_std_path(try_span, into_path, hir_vec![err_expr])
};
let from_err_expr =
self.wrap_in_try_constructor(sym::from_error, from_expr, unstable_span);
self.wrap_in_try_constructor(sym::from_error, into_expr, unstable_span);
let thin_attrs = ThinVec::from(attrs);
let catch_scope = self.catch_scopes.last().map(|x| *x);
let ret_expr = if let Some(catch_node) = catch_scope {
8 changes: 4 additions & 4 deletions src/librustc/infer/unify_key.rs
Original file line number Diff line number Diff line change
@@ -139,10 +139,10 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> {

// If one side is known, prefer that one.
(ConstVariableValue::Known { .. }, ConstVariableValue::Unknown { .. }) => {
Ok(value1.val)
value1.val
}
(ConstVariableValue::Unknown { .. }, ConstVariableValue::Known { .. }) => {
Ok(value2.val)
value2.val
}

// If both sides are *unknown*, it hardly matters, does it?
@@ -154,9 +154,9 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
// universe is the minimum of the two universes, because that is
// the one which contains the fewest names in scope.
let universe = cmp::min(universe1, universe2);
Ok(ConstVariableValue::Unknown { universe })
ConstVariableValue::Unknown { universe }
}
}?;
};

Ok(ConstVarValue {
origin: ConstVariableOrigin::ConstInference(DUMMY_SP),
4 changes: 2 additions & 2 deletions src/librustc/mir/interpret/mod.rs
Original file line number Diff line number Diff line change
@@ -159,7 +159,7 @@ impl<'s> AllocDecodingSession<'s> {

// Decode the AllocDiscriminant now so that we know if we have to reserve an
// AllocId.
let (alloc_kind, pos) = decoder.with_position(pos, |decoder| {
let (alloc_kind, pos) = decoder.with_position(pos, |decoder| -> Result<_, D::Error> {
let alloc_kind = AllocDiscriminant::decode(decoder)?;
Ok((alloc_kind, decoder.position()))
})?;
@@ -217,7 +217,7 @@ impl<'s> AllocDecodingSession<'s> {
};

// Now decode the actual data
let alloc_id = decoder.with_position(pos, |decoder| {
let alloc_id = decoder.with_position(pos, |decoder| -> Result<_, D::Error> {
match alloc_kind {
AllocDiscriminant::Alloc => {
let allocation = <&'tcx Allocation as Decodable>::decode(decoder)?;
2 changes: 1 addition & 1 deletion src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
@@ -2543,7 +2543,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
let variant_def = &adt_def.variants[variant];

let f = &mut *fmt;
ty::tls::with(|tcx| {
ty::tls::with(|tcx| -> fmt::Result {
let substs = tcx.lift(&substs).expect("could not lift for printing");
FmtPrinter::new(tcx, f, Namespace::ValueNS)
.print_def_path(variant_def.def_id, substs)?;
2 changes: 1 addition & 1 deletion src/librustc/ty/codec.rs
Original file line number Diff line number Diff line change
@@ -201,7 +201,7 @@ pub fn decode_predicates<'a, 'tcx, D>(decoder: &mut D)
}?;
Ok((predicate, Decodable::decode(decoder)?))
})
.collect::<Result<Vec<_>, _>>()?,
.collect::<Result<Vec<_>, D::Error>>()?,
})
}

2 changes: 1 addition & 1 deletion src/librustc/ty/instance.rs
Original file line number Diff line number Diff line change
@@ -174,7 +174,7 @@ impl<'tcx> InstanceDef<'tcx> {

impl<'tcx> fmt::Display for Instance<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
ty::tls::with(|tcx| {
ty::tls::with(|tcx| -> fmt::Result {
let substs = tcx.lift(&self.substs).expect("could not lift for printing");
FmtPrinter::new(tcx, &mut *f, Namespace::ValueNS)
.print_def_path(self.def_id(), substs)?;
18 changes: 11 additions & 7 deletions src/librustc/ty/layout.rs
Original file line number Diff line number Diff line change
@@ -249,7 +249,10 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
Prefixed(Size, Align),
}

let univariant_uninterned = |fields: &[TyLayout<'_>], repr: &ReprOptions, kind| {
let univariant_uninterned = |fields: &[TyLayout<'_>],
repr: &ReprOptions,
kind|
-> Result<_, LayoutError<'tcx>> {
let packed = repr.packed();
if packed && repr.align > 0 {
bug!("struct cannot be packed and aligned");
@@ -458,9 +461,10 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
size
})
};
let univariant = |fields: &[TyLayout<'_>], repr: &ReprOptions, kind| {
Ok(tcx.intern_layout(univariant_uninterned(fields, repr, kind)?))
};
let univariant =
|fields: &[TyLayout<'_>], repr: &ReprOptions, kind| -> Result<_, LayoutError<'tcx>> {
Ok(tcx.intern_layout(univariant_uninterned(fields, repr, kind)?))
};
debug_assert!(!ty.has_infer_types());

Ok(match ty.sty {
@@ -635,7 +639,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
align = align.max(variant.align);

Ok(variant)
}).collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
}).collect::<Result<IndexVec<VariantIdx, _>, LayoutError<'tcx>>>()?;

let abi = if prefix.abi.is_uninhabited() ||
variants.iter().all(|v| v.abi.is_uninhabited()) {
@@ -933,7 +937,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
align = align.max(st.align);

Ok(st)
}).collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
}).collect::<Result<IndexVec<VariantIdx, _>, LayoutError<'tcx>>>()?;

let offset = st[i].fields.offset(field_index) + niche.offset;
let size = st[i].size;
@@ -1048,7 +1052,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
size = cmp::max(size, st.size);
align = align.max(st.align);
Ok(st)
}).collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
}).collect::<Result<IndexVec<VariantIdx, _>, LayoutError<'tcx>>>()?;

// Align the maximum variant size to the largest alignment.
size = size.align_to(align.abi);
4 changes: 2 additions & 2 deletions src/librustc/ty/query/on_disk_cache.rs
Original file line number Diff line number Diff line change
@@ -202,7 +202,7 @@ impl<'sess> OnDiskCache<'sess> {
// Encode query results
let mut query_result_index = EncodedQueryResultIndex::new();

time(tcx.sess, "encode query results", || {
time(tcx.sess, "encode query results", || -> Result<_, E::Error> {
use crate::ty::query::queries::*;
let enc = &mut encoder;
let qri = &mut query_result_index;
@@ -260,7 +260,7 @@ impl<'sess> OnDiskCache<'sess> {

Ok((dep_node_index, pos))
})
.collect::<Result<_, _>>()?;
.collect::<Result<_, E::Error>>()?;

let interpret_alloc_index = {
let mut interpret_alloc_index = Vec::new();
2 changes: 1 addition & 1 deletion src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
@@ -253,7 +253,7 @@ pub fn run_compiler(
if let Some((ppm, opt_uii)) = pretty_info {
if ppm.needs_ast_map(&opt_uii) {
pretty::visit_crate(sess, &mut compiler.parse()?.peek_mut(), ppm);
compiler.global_ctxt()?.peek_mut().enter(|tcx| {
compiler.global_ctxt()?.peek_mut().enter(|tcx| -> interface::Result<_> {
let expanded_crate = compiler.expansion()?.take().0;
pretty::print_after_hir_lowering(
tcx,
1 change: 1 addition & 0 deletions src/librustc_metadata/lib.rs
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
#![feature(box_patterns)]
#![feature(drain_filter)]
#![feature(libc)]
#![feature(never_type)]
#![feature(nll)]
#![feature(proc_macro_internals)]
#![feature(proc_macro_quote)]
2 changes: 1 addition & 1 deletion src/librustc_mir/hair/constant.rs
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@ crate fn lit_to_const<'a, 'gcx, 'tcx>(
) -> Result<ty::Const<'tcx>, LitToConstError> {
use syntax::ast::*;

let trunc = |n| {
let trunc = |n| -> Result<_, LitToConstError> {
let param_ty = ParamEnv::reveal_all().and(tcx.lift_to_global(&ty).unwrap());
let width = tcx.layout_of(param_ty).map_err(|_| LitToConstError::Reported)?.size;
trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits());
2 changes: 2 additions & 0 deletions src/libsyntax_pos/symbol.rs
Original file line number Diff line number Diff line change
@@ -287,6 +287,8 @@ symbols! {
infer_static_outlives_requirements,
inline,
intel,
into,
Into,
into_iter,
IntoIterator,
into_result,
3 changes: 2 additions & 1 deletion src/test/ui/issues/issue-32709.stderr
Original file line number Diff line number Diff line change
@@ -4,7 +4,8 @@ error[E0277]: `?` couldn't convert the error to `()`
LL | Err(5)?;
| ^ the trait `std::convert::From<{integer}>` is not implemented for `()`
|
= note: required by `std::convert::From::from`
= note: required because of the requirements on the impl of `std::convert::Into<()>` for `{integer}`
= note: required by `std::convert::Into::into`

error: aborting due to previous error

3 changes: 2 additions & 1 deletion src/test/ui/try-block/try-block-bad-type.stderr
Original file line number Diff line number Diff line change
@@ -10,7 +10,8 @@ LL | Err("")?;
<i32 as std::convert::From<i8>>
<i32 as std::convert::From<std::num::NonZeroI32>>
and 2 others
= note: required by `std::convert::From::from`
= note: required because of the requirements on the impl of `std::convert::Into<i32>` for `&str`
= note: required by `std::convert::Into::into`

error[E0271]: type mismatch resolving `<std::result::Result<i32, i32> as std::ops::Try>::Ok == &str`
--> $DIR/try-block-bad-type.rs:12:9
3 changes: 2 additions & 1 deletion src/test/ui/try-on-option.stderr
Original file line number Diff line number Diff line change
@@ -4,7 +4,8 @@ error[E0277]: `?` couldn't convert the error to `()`
LL | x?;
| ^ the trait `std::convert::From<std::option::NoneError>` is not implemented for `()`
|
= note: required by `std::convert::From::from`
= note: required because of the requirements on the impl of `std::convert::Into<()>` for `std::option::NoneError`
= note: required by `std::convert::Into::into`

error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
--> $DIR/try-on-option.rs:13:5