Skip to content

Commit 51d4c32

Browse files
committed
fix(hygiene): Use inferred trait generic args even if path has qself
1 parent 1925867 commit 51d4c32

2 files changed

Lines changed: 36 additions & 22 deletions

File tree

mutest-emit/src/codegen/hygiene.rs

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -728,30 +728,29 @@ impl<'tcx, 'op> MacroExpansionSanitizer<'tcx, 'op> {
728728
// NOTE: We always add a qualified self type, so we can safely ignore the indicator return value.
729729
let _ = self.sanitize_path(path, qres.expect_non_local(), None);
730730

731-
// NOTE: There is no need to append bound param args if the path is already qualified, since
732-
// the necessary trait arguments should already be present in the corresponding path segment.
733-
if qself.is_none() {
734-
let generic_args_ast = match self.typeck_for(node_hir_id.owner).map(|typeck| &typeck.node_args(node_hir_id)[..]) {
735-
// Inferred generic args for the trait.
736-
Some(node_args @ [_, ..]) => {
737-
let trait_generics = self.tcx.generics_of(parent_def_id);
738-
let trait_args = &node_args[(trait_generics.has_self as usize)..trait_generics.count()];
739-
740-
self.sanitize_generic_args(trait_args, node_hir_id.owner.to_def_id(), qself_ty_hir.span)
741-
}
742-
743-
// Bound params from local trait bounds corresponding to parameter types to the trait subpath.
744-
_ if let Some(parent_path_segment_res) = parent_path_segment_res => {
745-
self.extract_local_trait_bound_params(parent_def_id, parent_path_segment_res, qself_ty_hir.span)
746-
}
747-
748-
_ => None,
749-
};
731+
// Extract param args for the trait reference in the qualified path.
732+
// These param args come from type-inference, if available, or
733+
// from bound params in local trait bounds in the current scope.
734+
let generic_args_ast = match self.typeck_for(node_hir_id.owner).map(|typeck| &typeck.node_args(node_hir_id)[..]) {
735+
// Inferred generic args for the trait.
736+
Some(node_args @ [_, ..]) => {
737+
let trait_generics = self.tcx.generics_of(parent_def_id);
738+
let trait_args = &node_args[(trait_generics.has_self as usize)..trait_generics.count()];
739+
740+
self.sanitize_generic_args(trait_args, node_hir_id.owner.to_def_id(), qself_ty_hir.span)
741+
}
750742

751-
if let Some(generic_args_ast) = generic_args_ast {
752-
let [.., parent_path_segment, _] = &mut path.segments[..] else { unreachable!() };
753-
parent_path_segment.args = Some(generic_args_ast);
743+
// Bound params from local trait bounds corresponding to parameter types to the trait subpath.
744+
_ if let Some(parent_path_segment_res) = parent_path_segment_res => {
745+
self.extract_local_trait_bound_params(parent_def_id, parent_path_segment_res, qself_ty_hir.span)
754746
}
747+
748+
_ => None,
749+
};
750+
// Append param args to the trait reference in the qualified path.
751+
if let Some(generic_args_ast) = generic_args_ast {
752+
let [.., parent_path_segment, _] = &mut path.segments[..] else { unreachable!() };
753+
parent_path_segment.args = Some(generic_args_ast);
755754
}
756755

757756
*qself = Some(P(ast::QSelf {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//@ build
2+
//@ stderr: empty
3+
4+
#![feature(decl_macro)]
5+
6+
use std::convert::TryFrom;
7+
8+
macro m() {
9+
let _ = <[Vec<u32>; 12]>::try_from(vec![vec![]; 12]).unwrap();
10+
}
11+
12+
#[test]
13+
fn test() {
14+
m!();
15+
}

0 commit comments

Comments
 (0)