diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index e69bf6eca90ef..e1578ab8fe90a 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1767,7 +1767,24 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { !needs_infer } Some(_) => true, - None => false, + None => { + if let Some(other) = tcx.impl_trait_ref(other_def) + && let Some(victim) = tcx.impl_trait_ref(victim_def) + && tcx.is_diagnostic_item(sym::AsRef, other.def_id) + && tcx.is_diagnostic_item(sym::AsRef, victim.def_id) + && other.substs.len() > 1 + && victim.substs.len() > 1 + && let ty::Slice(other) = other.substs.type_at(1).kind() + && let ty::Adt(def, substs) = victim.substs.type_at(1).kind() + && tcx.is_diagnostic_item(sym::Vec, def.did()) + { + // If this is an `AsRef` implementation that can go either way for + // `AsRef<[T]>` or `AsRef`, prefer the former. + other == &substs.type_at(0) + } else { + false + } + } } } else { false diff --git a/src/test/ui/inference/vec-from-array-ref-impl.rs b/src/test/ui/inference/vec-from-array-ref-impl.rs new file mode 100644 index 0000000000000..58588f0eacd59 --- /dev/null +++ b/src/test/ui/inference/vec-from-array-ref-impl.rs @@ -0,0 +1,14 @@ +// check-pass + +#[derive(Clone)] +struct Constraint; + +fn constraints(constraints: C) +where C: Into> +{ + let _: Vec = constraints.into(); +} + +fn main() { + constraints(vec![Constraint].as_ref()); +}