/// Check if a type matches this requirement.
Check if a type matches this requirement.
Check if a type matches this requirement .
pub fn matches(&self, ty: &Ty) -> bool {
        if let Ty::Subprog(ref ty) = *ty {
            if !self.return_type.is_any()
                && !ty
                    .ret
                    .as_ref()
                    .map(|t| self.return_type.matches(t))
                    .unwrap_or(false)
            {
                debugln!("return type mismatch: {} vs {:?}", ty, self);
                return false;
            }
            if self.positional.len() > ty.args.len() {
                debugln!("positional length mismatch: {} vs {:?}", ty, self);
                return false;
            }
            let mut arg_iter = ty.args.iter();
            for req in &self.positional {
                let arg = arg_iter.next().unwrap(); // never fails due to above check
                if !req.matches(&arg.ty) {
                    debugln!(
                        "positional mismatch: {} vs {:?} in {} vs {:?}",
                        arg.ty,
                        req,
                        ty,
                        self
                    );
                    return false;
                }
            }
            let mut unhandled_names: HashSet<_> = self.named.keys().collect();
            for arg in arg_iter {
                let name = match arg.name {
                    Some(name) => name,
                    None => {
                        debugln!(
                            "unhandled positional arg: {} in {} vs {:?}",
                            arg.ty,
                            ty,
                            self
                        );
                        return false;
                    }
                };
                let req = match self.named.get(&name) {
                    Some(req) => req,
                    None => {
                        debugln!("unknown named arg: {} in {} vs {:?}", name, ty, self);
                        return false;
                    }
                };
                if !req.matches(&arg.ty) {
                    debugln!(
                        "named mismatch `{}`: {} vs {:?} in {} vs {:?}",
                        name,
                        arg.ty,
                        req,
                        ty,
                        self
                    );
                    return false;
                }
                unhandled_names.remove(&name);
            }
            unhandled_names.is_empty()
        } else {
            false
        }
    }
pub fn matches ( & self , ty : & Ty ) -> bool { if let Ty :: Subprog ( ref ty ) = * ty { if ! self . return_type . is_any ( ) && ! ty . ret . as_ref ( ) . map ( | t | self . return_type . matches ( t ) ) . unwrap_or ( false ) { debugln ! ( " " ty self ) ; return false ; } if self . positional . len ( ) > ty . args . len ( ) { debugln ! ( " " ty self ) ; return false ; } let mut arg_iter = ty . args . iter ( ) ; for req in & self . positional { let arg = arg_iter . next ( ) . unwrap ( ) ; // never fails due to above check if ! req . matches ( & arg . ty ) { debugln ! ( " " arg ty req ty self ) ; return false ; } } let mut unhandled_names : HashSet < _ > = self . named . keys ( ) . collect ( ) ; for arg in arg_iter { let name = match arg . name { Some ( name ) => name , None => { debugln ! ( " " arg ty ty self ) ; return false ; } } ; let req = match self . named . get ( & name ) { Some ( req ) => req , None => { debugln ! ( " " name ty self ) ; return false ; } } ; if ! req . matches ( & arg . ty ) { debugln ! ( " " name arg ty req ty self ) ; return false ; } unhandled_names . remove ( & name ) ; } unhandled_names . is_empty ( ) } else { false } }
Check if a type matches this requirement.
Check if a type matches this requirement .
&self
ty
&Ty